Re: [PATCH 3/3] scsi:ufs:add hi3660 ufs driver code

2017-06-09 Thread Guodong Xu
On Sat, Jun 10, 2017 at 9:21 AM, butao  wrote:
> add hi3660 ufs driver code
>
> Signed-off-by: Geng Jianfeng 
> Signed-off-by: Bu Tao 
> Signed-off-by: Zang Leigang 
> Signed-off-by: Yu Jianfeng 
> ---
>  drivers/scsi/ufs/Kconfig  |   8 +
>  drivers/scsi/ufs/Makefile |   1 +
>  drivers/scsi/ufs/ufs-hi3660.c | 715 
> ++
>  drivers/scsi/ufs/ufs-hi3660.h | 170 ++
>  4 files changed, 894 insertions(+)
>  mode change 100644 => 100755 drivers/scsi/ufs/Kconfig
>  mode change 100644 => 100755 drivers/scsi/ufs/Makefile
>  create mode 100755 drivers/scsi/ufs/ufs-hi3660.c
>  create mode 100755 drivers/scsi/ufs/ufs-hi3660.h

mode 755? Err.

>
> diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
> old mode 100644
> new mode 100755
> index e27b4d4e6ae2..119604ea0aae
> --- a/drivers/scsi/ufs/Kconfig
> +++ b/drivers/scsi/ufs/Kconfig
> @@ -80,6 +80,14 @@ config SCSI_UFSHCD_PLATFORM
>
>   If unsure, say N.
>
> +config SCSI_UFS_HI3660
> +   tristate "Hisilicon Hi3660 UFS controller platform driver"
> +   depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
> +   help
> + This selects the Hisilicon HI3660 additions to UFSHCD platform 
> driver.
> +
> + If unsure, say N.
> +

Please also add "SCSI_UFS_HI3660=y" into arch/arm64/configs/defconfig,
and submit as a separate patch.

-Guodong


>  config SCSI_UFS_DWC_TC_PLATFORM
> tristate "DesignWare platform support using a G210 Test Chip"
> depends on SCSI_UFSHCD_PLATFORM
> diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
> old mode 100644
> new mode 100755
> index 6e77cb0bfee9..ae880189f018
> --- a/drivers/scsi/ufs/Makefile
> +++ b/drivers/scsi/ufs/Makefile
> @@ -2,6 +2,7 @@
>  obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o 
> tc-dwc-g210.o
>  obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o 
> tc-dwc-g210.o
>  obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
> +obj-$(CONFIG_SCSI_UFS_HI3660) += ufs-hi3660.o
>  obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
>  obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
>  obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
> diff --git a/drivers/scsi/ufs/ufs-hi3660.c b/drivers/scsi/ufs/ufs-hi3660.c
> new file mode 100755
> index ..ccbcb01f6863
> --- /dev/null
> +++ b/drivers/scsi/ufs/ufs-hi3660.c
> @@ -0,0 +1,715 @@
> +/*
> + * Copyright (c) 2016-2017 Linaro Ltd.
> + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "ufshcd.h"
> +#include "ufshcd-pltfrm.h"
> +#include "unipro.h"
> +#include "ufs-hi3660.h"
> +#include "ufshci.h"
> +
> +static int ufs_hi3660_check_hibern8(struct ufs_hba *hba)
> +{
> +   int err;
> +   u32 tx_fsm_val_0;
> +   u32 tx_fsm_val_1;
> +   unsigned long timeout = jiffies + 
> msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
> +
> +   do {
> +   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 0),
> + _fsm_val_0);
> +   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 1),
> + _fsm_val_1);
> +   if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && tx_fsm_val_1 == 
> TX_FSM_HIBERN8))
> +   break;
> +
> +   /* sleep for max. 200us */
> +   usleep_range(100, 200);
> +   } while (time_before(jiffies, timeout));
> +
> +   /*
> +* we might have scheduled out for long during polling so
> +* check the state again.
> +*/
> +   if (time_after(jiffies, timeout)) {
> +   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 0),
> +_fsm_val_0);
> +   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 1),
> +_fsm_val_1);
> +   }
> +
> +   if (err) {
> +   dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
> +   __func__, err);
> +   } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || tx_fsm_val_1 != 
> TX_FSM_HIBERN8) {
> +   err = -1;
> +   dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, 
> lane1 = %d\n",
> +   __func__, tx_fsm_val_0, tx_fsm_val_1);
> +   }
> +
> +   return err;
> +}
> +
> +static void ufs_hi3660_clk_init(struct ufs_hba *hba)
> +{
> +   struct 

Re: [PATCH 3/3] scsi:ufs:add hi3660 ufs driver code

2017-06-09 Thread Guodong Xu
On Sat, Jun 10, 2017 at 9:21 AM, butao  wrote:
> add hi3660 ufs driver code
>
> Signed-off-by: Geng Jianfeng 
> Signed-off-by: Bu Tao 
> Signed-off-by: Zang Leigang 
> Signed-off-by: Yu Jianfeng 
> ---
>  drivers/scsi/ufs/Kconfig  |   8 +
>  drivers/scsi/ufs/Makefile |   1 +
>  drivers/scsi/ufs/ufs-hi3660.c | 715 
> ++
>  drivers/scsi/ufs/ufs-hi3660.h | 170 ++
>  4 files changed, 894 insertions(+)
>  mode change 100644 => 100755 drivers/scsi/ufs/Kconfig
>  mode change 100644 => 100755 drivers/scsi/ufs/Makefile
>  create mode 100755 drivers/scsi/ufs/ufs-hi3660.c
>  create mode 100755 drivers/scsi/ufs/ufs-hi3660.h

mode 755? Err.

>
> diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
> old mode 100644
> new mode 100755
> index e27b4d4e6ae2..119604ea0aae
> --- a/drivers/scsi/ufs/Kconfig
> +++ b/drivers/scsi/ufs/Kconfig
> @@ -80,6 +80,14 @@ config SCSI_UFSHCD_PLATFORM
>
>   If unsure, say N.
>
> +config SCSI_UFS_HI3660
> +   tristate "Hisilicon Hi3660 UFS controller platform driver"
> +   depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
> +   help
> + This selects the Hisilicon HI3660 additions to UFSHCD platform 
> driver.
> +
> + If unsure, say N.
> +

Please also add "SCSI_UFS_HI3660=y" into arch/arm64/configs/defconfig,
and submit as a separate patch.

-Guodong


>  config SCSI_UFS_DWC_TC_PLATFORM
> tristate "DesignWare platform support using a G210 Test Chip"
> depends on SCSI_UFSHCD_PLATFORM
> diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
> old mode 100644
> new mode 100755
> index 6e77cb0bfee9..ae880189f018
> --- a/drivers/scsi/ufs/Makefile
> +++ b/drivers/scsi/ufs/Makefile
> @@ -2,6 +2,7 @@
>  obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o 
> tc-dwc-g210.o
>  obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o 
> tc-dwc-g210.o
>  obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
> +obj-$(CONFIG_SCSI_UFS_HI3660) += ufs-hi3660.o
>  obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
>  obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
>  obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
> diff --git a/drivers/scsi/ufs/ufs-hi3660.c b/drivers/scsi/ufs/ufs-hi3660.c
> new file mode 100755
> index ..ccbcb01f6863
> --- /dev/null
> +++ b/drivers/scsi/ufs/ufs-hi3660.c
> @@ -0,0 +1,715 @@
> +/*
> + * Copyright (c) 2016-2017 Linaro Ltd.
> + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "ufshcd.h"
> +#include "ufshcd-pltfrm.h"
> +#include "unipro.h"
> +#include "ufs-hi3660.h"
> +#include "ufshci.h"
> +
> +static int ufs_hi3660_check_hibern8(struct ufs_hba *hba)
> +{
> +   int err;
> +   u32 tx_fsm_val_0;
> +   u32 tx_fsm_val_1;
> +   unsigned long timeout = jiffies + 
> msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
> +
> +   do {
> +   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 0),
> + _fsm_val_0);
> +   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 1),
> + _fsm_val_1);
> +   if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && tx_fsm_val_1 == 
> TX_FSM_HIBERN8))
> +   break;
> +
> +   /* sleep for max. 200us */
> +   usleep_range(100, 200);
> +   } while (time_before(jiffies, timeout));
> +
> +   /*
> +* we might have scheduled out for long during polling so
> +* check the state again.
> +*/
> +   if (time_after(jiffies, timeout)) {
> +   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 0),
> +_fsm_val_0);
> +   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
> 1),
> +_fsm_val_1);
> +   }
> +
> +   if (err) {
> +   dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
> +   __func__, err);
> +   } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || tx_fsm_val_1 != 
> TX_FSM_HIBERN8) {
> +   err = -1;
> +   dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, 
> lane1 = %d\n",
> +   __func__, tx_fsm_val_0, tx_fsm_val_1);
> +   }
> +
> +   return err;
> +}
> +
> +static void ufs_hi3660_clk_init(struct ufs_hba *hba)
> +{
> +   struct ufs_hi3660_host *host = ufshcd_get_variant(hba);
> +
> +   ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
> +  

[PATCH 3/3] scsi:ufs:add hi3660 ufs driver code

2017-06-09 Thread butao
add hi3660 ufs driver code

Signed-off-by: Geng Jianfeng 
Signed-off-by: Bu Tao 
Signed-off-by: Zang Leigang 
Signed-off-by: Yu Jianfeng 
---
 drivers/scsi/ufs/Kconfig  |   8 +
 drivers/scsi/ufs/Makefile |   1 +
 drivers/scsi/ufs/ufs-hi3660.c | 715 ++
 drivers/scsi/ufs/ufs-hi3660.h | 170 ++
 4 files changed, 894 insertions(+)
 mode change 100644 => 100755 drivers/scsi/ufs/Kconfig
 mode change 100644 => 100755 drivers/scsi/ufs/Makefile
 create mode 100755 drivers/scsi/ufs/ufs-hi3660.c
 create mode 100755 drivers/scsi/ufs/ufs-hi3660.h

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
old mode 100644
new mode 100755
index e27b4d4e6ae2..119604ea0aae
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -80,6 +80,14 @@ config SCSI_UFSHCD_PLATFORM
 
  If unsure, say N.
 
+config SCSI_UFS_HI3660
+   tristate "Hisilicon Hi3660 UFS controller platform driver"
+   depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
+   help
+ This selects the Hisilicon HI3660 additions to UFSHCD platform driver.
+
+ If unsure, say N.
+
 config SCSI_UFS_DWC_TC_PLATFORM
tristate "DesignWare platform support using a G210 Test Chip"
depends on SCSI_UFSHCD_PLATFORM
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
old mode 100644
new mode 100755
index 6e77cb0bfee9..ae880189f018
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
+obj-$(CONFIG_SCSI_UFS_HI3660) += ufs-hi3660.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufs-hi3660.c b/drivers/scsi/ufs/ufs-hi3660.c
new file mode 100755
index ..ccbcb01f6863
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-hi3660.c
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2016-2017 Linaro Ltd.
+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ufshcd.h"
+#include "ufshcd-pltfrm.h"
+#include "unipro.h"
+#include "ufs-hi3660.h"
+#include "ufshci.h"
+
+static int ufs_hi3660_check_hibern8(struct ufs_hba *hba)
+{
+   int err;
+   u32 tx_fsm_val_0;
+   u32 tx_fsm_val_1;
+   unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
+
+   do {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+ _fsm_val_0);
+   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
1),
+ _fsm_val_1);
+   if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && tx_fsm_val_1 == 
TX_FSM_HIBERN8))
+   break;
+
+   /* sleep for max. 200us */
+   usleep_range(100, 200);
+   } while (time_before(jiffies, timeout));
+
+   /*
+* we might have scheduled out for long during polling so
+* check the state again.
+*/
+   if (time_after(jiffies, timeout)) {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+_fsm_val_0);
+   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
1),
+_fsm_val_1);
+   }
+
+   if (err) {
+   dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
+   __func__, err);
+   } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || tx_fsm_val_1 != 
TX_FSM_HIBERN8) {
+   err = -1;
+   dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 
= %d\n",
+   __func__, tx_fsm_val_0, tx_fsm_val_1);
+   }
+
+   return err;
+}
+
+static void ufs_hi3660_clk_init(struct ufs_hba *hba)
+{
+   struct ufs_hi3660_host *host = ufshcd_get_variant(hba);
+
+   ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
+   if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN)
+   mdelay(1);
+   /* use abb clk */
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL);
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN);
+   /* open mphy ref clk */
+   ufs_sys_ctrl_set_bits(host, 

[PATCH 3/3] scsi:ufs:add hi3660 ufs driver code

2017-06-09 Thread butao
add hi3660 ufs driver code

Signed-off-by: Geng Jianfeng 
Signed-off-by: Bu Tao 
Signed-off-by: Zang Leigang 
Signed-off-by: Yu Jianfeng 
---
 drivers/scsi/ufs/Kconfig  |   8 +
 drivers/scsi/ufs/Makefile |   1 +
 drivers/scsi/ufs/ufs-hi3660.c | 715 ++
 drivers/scsi/ufs/ufs-hi3660.h | 170 ++
 4 files changed, 894 insertions(+)
 mode change 100644 => 100755 drivers/scsi/ufs/Kconfig
 mode change 100644 => 100755 drivers/scsi/ufs/Makefile
 create mode 100755 drivers/scsi/ufs/ufs-hi3660.c
 create mode 100755 drivers/scsi/ufs/ufs-hi3660.h

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
old mode 100644
new mode 100755
index e27b4d4e6ae2..119604ea0aae
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -80,6 +80,14 @@ config SCSI_UFSHCD_PLATFORM
 
  If unsure, say N.
 
+config SCSI_UFS_HI3660
+   tristate "Hisilicon Hi3660 UFS controller platform driver"
+   depends on (ARCH_HISI || COMPILE_TEST) && SCSI_UFSHCD_PLATFORM
+   help
+ This selects the Hisilicon HI3660 additions to UFSHCD platform driver.
+
+ If unsure, say N.
+
 config SCSI_UFS_DWC_TC_PLATFORM
tristate "DesignWare platform support using a G210 Test Chip"
depends on SCSI_UFSHCD_PLATFORM
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
old mode 100644
new mode 100755
index 6e77cb0bfee9..ae880189f018
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o 
tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
+obj-$(CONFIG_SCSI_UFS_HI3660) += ufs-hi3660.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufs-hi3660.c b/drivers/scsi/ufs/ufs-hi3660.c
new file mode 100755
index ..ccbcb01f6863
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-hi3660.c
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2016-2017 Linaro Ltd.
+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ufshcd.h"
+#include "ufshcd-pltfrm.h"
+#include "unipro.h"
+#include "ufs-hi3660.h"
+#include "ufshci.h"
+
+static int ufs_hi3660_check_hibern8(struct ufs_hba *hba)
+{
+   int err;
+   u32 tx_fsm_val_0;
+   u32 tx_fsm_val_1;
+   unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
+
+   do {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+ _fsm_val_0);
+   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
1),
+ _fsm_val_1);
+   if (err || (tx_fsm_val_0 == TX_FSM_HIBERN8 && tx_fsm_val_1 == 
TX_FSM_HIBERN8))
+   break;
+
+   /* sleep for max. 200us */
+   usleep_range(100, 200);
+   } while (time_before(jiffies, timeout));
+
+   /*
+* we might have scheduled out for long during polling so
+* check the state again.
+*/
+   if (time_after(jiffies, timeout)) {
+   err = ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 0),
+_fsm_val_0);
+   err |= ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE, 
1),
+_fsm_val_1);
+   }
+
+   if (err) {
+   dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
+   __func__, err);
+   } else if (tx_fsm_val_0 != TX_FSM_HIBERN8 || tx_fsm_val_1 != 
TX_FSM_HIBERN8) {
+   err = -1;
+   dev_err(hba->dev, "%s: invalid TX_FSM_STATE, lane0 = %d, lane1 
= %d\n",
+   __func__, tx_fsm_val_0, tx_fsm_val_1);
+   }
+
+   return err;
+}
+
+static void ufs_hi3660_clk_init(struct ufs_hba *hba)
+{
+   struct ufs_hi3660_host *host = ufshcd_get_variant(hba);
+
+   ufs_sys_ctrl_clr_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
+   if (ufs_sys_ctrl_readl(host, PHY_CLK_CTRL) & BIT_SYSCTRL_REF_CLOCK_EN)
+   mdelay(1);
+   /* use abb clk */
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_SRC_SEl, UFS_SYSCTRL);
+   ufs_sys_ctrl_clr_bits(host, BIT_UFS_REFCLK_ISO_EN, PHY_ISO_EN);
+   /* open mphy ref clk */
+   ufs_sys_ctrl_set_bits(host, BIT_SYSCTRL_REF_CLOCK_EN, PHY_CLK_CTRL);
+}
+
+static void ufs_hi3660_soc_init(struct ufs_hba *hba)
+{
+   struct