Re: [PATCH v7 4/5] phy: qcom-ufs: add support for 14nm phy

2015-01-15 Thread dovl
Reviewed-by: Dov Levenglick 

> This change adds a support for a 14nm qcom-ufs phy that is
> required in platforms that use ufs-qcom controller.
>
> Signed-off-by: Yaniv Gardi 
>
> ---
>  drivers/phy/Makefile|   1 +
>  drivers/phy/phy-qcom-ufs-qmp-14nm.c | 201
> 
>  drivers/phy/phy-qcom-ufs-qmp-14nm.h | 177 +++
>  3 files changed, 379 insertions(+)
>  create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.c
>  create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.h
>
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index 781b2fa..cfbb720 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -36,3 +36,4 @@ obj-$(CONFIG_PHY_STIH407_USB)   +=
> phy-stih407-usb.o
>  obj-$(CONFIG_PHY_STIH41X_USB)+= phy-stih41x-usb.o
>  obj-$(CONFIG_PHY_QCOM_UFS)   += phy-qcom-ufs.o
>  obj-$(CONFIG_PHY_QCOM_UFS)   += phy-qcom-ufs-qmp-20nm.o
> +obj-$(CONFIG_PHY_QCOM_UFS)   += phy-qcom-ufs-qmp-14nm.o
> diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> new file mode 100644
> index 000..f5fc50a
> --- /dev/null
> +++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
> @@ -0,0 +1,201 @@
> +/*
> + * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include "phy-qcom-ufs-qmp-14nm.h"
> +
> +#define UFS_PHY_NAME "ufs_phy_qmp_14nm"
> +#define UFS_PHY_VDDA_PHY_UV  (925000)
> +
> +static
> +int ufs_qcom_phy_qmp_14nm_phy_calibrate(struct ufs_qcom_phy
> *ufs_qcom_phy,
> + bool is_rate_B)
> +{
> + int tbl_size_A = ARRAY_SIZE(phy_cal_table_rate_A);
> + int tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B);
> + int err;
> +
> + err = ufs_qcom_phy_calibrate(ufs_qcom_phy, phy_cal_table_rate_A,
> + tbl_size_A, phy_cal_table_rate_B, tbl_size_B, is_rate_B);
> +
> + if (err)
> + dev_err(ufs_qcom_phy->dev,
> + "%s: ufs_qcom_phy_calibrate() failed %d\n",
> + __func__, err);
> + return err;
> +}
> +
> +static
> +void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy
> *phy_common)
> +{
> + phy_common->quirks =
> + UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE;
> +}
> +
> +static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy)
> +{
> + struct ufs_qcom_phy_qmp_14nm *phy = phy_get_drvdata(generic_phy);
> + struct ufs_qcom_phy *phy_common = >common_cfg;
> + int err;
> +
> + err = ufs_qcom_phy_init_clks(generic_phy, phy_common);
> + if (err) {
> + dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks()
> failed %d\n",
> + __func__, err);
> + goto out;
> + }
> +
> + err = ufs_qcom_phy_init_vregulators(generic_phy, phy_common);
> + if (err) {
> + dev_err(phy_common->dev, "%s:
> ufs_qcom_phy_init_vregulators() failed %d\n",
> + __func__, err);
> + goto out;
> + }
> + phy_common->vdda_phy.max_uV = UFS_PHY_VDDA_PHY_UV;
> + phy_common->vdda_phy.min_uV = UFS_PHY_VDDA_PHY_UV;
> +
> + ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common);
> +
> +out:
> + return err;
> +}
> +
> +static
> +void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy *phy, bool
> val)
> +{
> + writel_relaxed(val ? 0x1 : 0x0, phy->mmio +
> UFS_PHY_POWER_DOWN_CONTROL);
> + /*
> +  * Before any transactions involving PHY, ensure PHY knows
> +  * that it's analog rail is powered ON (or OFF).
> +  */
> + mb();
> +}
> +
> +static inline
> +void ufs_qcom_phy_qmp_14nm_set_tx_lane_enable(struct ufs_qcom_phy *phy,
> u32 val)
> +{
> + /*
> +  * 14nm PHY does not have TX_LANE_ENABLE register.
> +  * Implement this function so as not to propagate error to caller.
> +  */
> +}
> +
> +static inline void ufs_qcom_phy_qmp_14nm_start_serdes(struct ufs_qcom_phy
> *phy)
> +{
> + u32 tmp;
> +
> + tmp = readl_relaxed(phy->mmio + UFS_PHY_PHY_START);
> + tmp &= ~MASK_SERDES_START;
> + tmp |= (1 << OFFSET_SERDES_START);
> + writel_relaxed(tmp, phy->mmio + UFS_PHY_PHY_START);
> + /* Ensure register value is committed */
> + mb();
> +}
> +
> +static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy
> *phy_common)
> +{
> + int err = 0;
> + u32 val;
> +
> + err = readl_poll_timeout(phy_common->mmio +
> UFS_PHY_PCS_READY_STATUS,
> + val, (val & 

[PATCH v7 4/5] phy: qcom-ufs: add support for 14nm phy

2015-01-15 Thread Yaniv Gardi
This change adds a support for a 14nm qcom-ufs phy that is
required in platforms that use ufs-qcom controller.

Signed-off-by: Yaniv Gardi 

---
 drivers/phy/Makefile|   1 +
 drivers/phy/phy-qcom-ufs-qmp-14nm.c | 201 
 drivers/phy/phy-qcom-ufs-qmp-14nm.h | 177 +++
 3 files changed, 379 insertions(+)
 create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.c
 create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.h

diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 781b2fa..cfbb720 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -36,3 +36,4 @@ obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
 obj-$(CONFIG_PHY_STIH41X_USB)  += phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
+obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c 
b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
new file mode 100644
index 000..f5fc50a
--- /dev/null
+++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "phy-qcom-ufs-qmp-14nm.h"
+
+#define UFS_PHY_NAME "ufs_phy_qmp_14nm"
+#define UFS_PHY_VDDA_PHY_UV(925000)
+
+static
+int ufs_qcom_phy_qmp_14nm_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
+   bool is_rate_B)
+{
+   int tbl_size_A = ARRAY_SIZE(phy_cal_table_rate_A);
+   int tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B);
+   int err;
+
+   err = ufs_qcom_phy_calibrate(ufs_qcom_phy, phy_cal_table_rate_A,
+   tbl_size_A, phy_cal_table_rate_B, tbl_size_B, is_rate_B);
+
+   if (err)
+   dev_err(ufs_qcom_phy->dev,
+   "%s: ufs_qcom_phy_calibrate() failed %d\n",
+   __func__, err);
+   return err;
+}
+
+static
+void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common)
+{
+   phy_common->quirks =
+   UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE;
+}
+
+static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy)
+{
+   struct ufs_qcom_phy_qmp_14nm *phy = phy_get_drvdata(generic_phy);
+   struct ufs_qcom_phy *phy_common = >common_cfg;
+   int err;
+
+   err = ufs_qcom_phy_init_clks(generic_phy, phy_common);
+   if (err) {
+   dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_clks() failed 
%d\n",
+   __func__, err);
+   goto out;
+   }
+
+   err = ufs_qcom_phy_init_vregulators(generic_phy, phy_common);
+   if (err) {
+   dev_err(phy_common->dev, "%s: ufs_qcom_phy_init_vregulators() 
failed %d\n",
+   __func__, err);
+   goto out;
+   }
+   phy_common->vdda_phy.max_uV = UFS_PHY_VDDA_PHY_UV;
+   phy_common->vdda_phy.min_uV = UFS_PHY_VDDA_PHY_UV;
+
+   ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common);
+
+out:
+   return err;
+}
+
+static
+void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy *phy, bool val)
+{
+   writel_relaxed(val ? 0x1 : 0x0, phy->mmio + UFS_PHY_POWER_DOWN_CONTROL);
+   /*
+* Before any transactions involving PHY, ensure PHY knows
+* that it's analog rail is powered ON (or OFF).
+*/
+   mb();
+}
+
+static inline
+void ufs_qcom_phy_qmp_14nm_set_tx_lane_enable(struct ufs_qcom_phy *phy, u32 
val)
+{
+   /*
+* 14nm PHY does not have TX_LANE_ENABLE register.
+* Implement this function so as not to propagate error to caller.
+*/
+}
+
+static inline void ufs_qcom_phy_qmp_14nm_start_serdes(struct ufs_qcom_phy *phy)
+{
+   u32 tmp;
+
+   tmp = readl_relaxed(phy->mmio + UFS_PHY_PHY_START);
+   tmp &= ~MASK_SERDES_START;
+   tmp |= (1 << OFFSET_SERDES_START);
+   writel_relaxed(tmp, phy->mmio + UFS_PHY_PHY_START);
+   /* Ensure register value is committed */
+   mb();
+}
+
+static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy *phy_common)
+{
+   int err = 0;
+   u32 val;
+
+   err = readl_poll_timeout(phy_common->mmio + UFS_PHY_PCS_READY_STATUS,
+   val, (val & MASK_PCS_READY), 10, 100);
+   if (err)
+   dev_err(phy_common->dev, "%s: poll for pcs failed err = %d\n",
+   __func__, err);
+   return err;
+}
+
+static struct phy_ops 

Re: [PATCH v7 4/5] phy: qcom-ufs: add support for 14nm phy

2015-01-15 Thread dovl
Reviewed-by: Dov Levenglick d...@codeaurora.org

 This change adds a support for a 14nm qcom-ufs phy that is
 required in platforms that use ufs-qcom controller.

 Signed-off-by: Yaniv Gardi yga...@codeaurora.org

 ---
  drivers/phy/Makefile|   1 +
  drivers/phy/phy-qcom-ufs-qmp-14nm.c | 201
 
  drivers/phy/phy-qcom-ufs-qmp-14nm.h | 177 +++
  3 files changed, 379 insertions(+)
  create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.c
  create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.h

 diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
 index 781b2fa..cfbb720 100644
 --- a/drivers/phy/Makefile
 +++ b/drivers/phy/Makefile
 @@ -36,3 +36,4 @@ obj-$(CONFIG_PHY_STIH407_USB)   +=
 phy-stih407-usb.o
  obj-$(CONFIG_PHY_STIH41X_USB)+= phy-stih41x-usb.o
  obj-$(CONFIG_PHY_QCOM_UFS)   += phy-qcom-ufs.o
  obj-$(CONFIG_PHY_QCOM_UFS)   += phy-qcom-ufs-qmp-20nm.o
 +obj-$(CONFIG_PHY_QCOM_UFS)   += phy-qcom-ufs-qmp-14nm.o
 diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c
 b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
 new file mode 100644
 index 000..f5fc50a
 --- /dev/null
 +++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
 @@ -0,0 +1,201 @@
 +/*
 + * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 and
 + * only version 2 as published by the Free Software Foundation.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + */
 +
 +#include phy-qcom-ufs-qmp-14nm.h
 +
 +#define UFS_PHY_NAME ufs_phy_qmp_14nm
 +#define UFS_PHY_VDDA_PHY_UV  (925000)
 +
 +static
 +int ufs_qcom_phy_qmp_14nm_phy_calibrate(struct ufs_qcom_phy
 *ufs_qcom_phy,
 + bool is_rate_B)
 +{
 + int tbl_size_A = ARRAY_SIZE(phy_cal_table_rate_A);
 + int tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B);
 + int err;
 +
 + err = ufs_qcom_phy_calibrate(ufs_qcom_phy, phy_cal_table_rate_A,
 + tbl_size_A, phy_cal_table_rate_B, tbl_size_B, is_rate_B);
 +
 + if (err)
 + dev_err(ufs_qcom_phy-dev,
 + %s: ufs_qcom_phy_calibrate() failed %d\n,
 + __func__, err);
 + return err;
 +}
 +
 +static
 +void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy
 *phy_common)
 +{
 + phy_common-quirks =
 + UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE;
 +}
 +
 +static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy)
 +{
 + struct ufs_qcom_phy_qmp_14nm *phy = phy_get_drvdata(generic_phy);
 + struct ufs_qcom_phy *phy_common = phy-common_cfg;
 + int err;
 +
 + err = ufs_qcom_phy_init_clks(generic_phy, phy_common);
 + if (err) {
 + dev_err(phy_common-dev, %s: ufs_qcom_phy_init_clks()
 failed %d\n,
 + __func__, err);
 + goto out;
 + }
 +
 + err = ufs_qcom_phy_init_vregulators(generic_phy, phy_common);
 + if (err) {
 + dev_err(phy_common-dev, %s:
 ufs_qcom_phy_init_vregulators() failed %d\n,
 + __func__, err);
 + goto out;
 + }
 + phy_common-vdda_phy.max_uV = UFS_PHY_VDDA_PHY_UV;
 + phy_common-vdda_phy.min_uV = UFS_PHY_VDDA_PHY_UV;
 +
 + ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common);
 +
 +out:
 + return err;
 +}
 +
 +static
 +void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy *phy, bool
 val)
 +{
 + writel_relaxed(val ? 0x1 : 0x0, phy-mmio +
 UFS_PHY_POWER_DOWN_CONTROL);
 + /*
 +  * Before any transactions involving PHY, ensure PHY knows
 +  * that it's analog rail is powered ON (or OFF).
 +  */
 + mb();
 +}
 +
 +static inline
 +void ufs_qcom_phy_qmp_14nm_set_tx_lane_enable(struct ufs_qcom_phy *phy,
 u32 val)
 +{
 + /*
 +  * 14nm PHY does not have TX_LANE_ENABLE register.
 +  * Implement this function so as not to propagate error to caller.
 +  */
 +}
 +
 +static inline void ufs_qcom_phy_qmp_14nm_start_serdes(struct ufs_qcom_phy
 *phy)
 +{
 + u32 tmp;
 +
 + tmp = readl_relaxed(phy-mmio + UFS_PHY_PHY_START);
 + tmp = ~MASK_SERDES_START;
 + tmp |= (1  OFFSET_SERDES_START);
 + writel_relaxed(tmp, phy-mmio + UFS_PHY_PHY_START);
 + /* Ensure register value is committed */
 + mb();
 +}
 +
 +static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy
 *phy_common)
 +{
 + int err = 0;
 + u32 val;
 +
 + err = readl_poll_timeout(phy_common-mmio +
 UFS_PHY_PCS_READY_STATUS,
 + val, (val  MASK_PCS_READY), 10, 100);
 + if (err)
 + dev_err(phy_common-dev, %s: poll for pcs failed err =
 %d\n,
 + 

[PATCH v7 4/5] phy: qcom-ufs: add support for 14nm phy

2015-01-15 Thread Yaniv Gardi
This change adds a support for a 14nm qcom-ufs phy that is
required in platforms that use ufs-qcom controller.

Signed-off-by: Yaniv Gardi yga...@codeaurora.org

---
 drivers/phy/Makefile|   1 +
 drivers/phy/phy-qcom-ufs-qmp-14nm.c | 201 
 drivers/phy/phy-qcom-ufs-qmp-14nm.h | 177 +++
 3 files changed, 379 insertions(+)
 create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.c
 create mode 100644 drivers/phy/phy-qcom-ufs-qmp-14nm.h

diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 781b2fa..cfbb720 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -36,3 +36,4 @@ obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
 obj-$(CONFIG_PHY_STIH41X_USB)  += phy-stih41x-usb.o
 obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
 obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
+obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
diff --git a/drivers/phy/phy-qcom-ufs-qmp-14nm.c 
b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
new file mode 100644
index 000..f5fc50a
--- /dev/null
+++ b/drivers/phy/phy-qcom-ufs-qmp-14nm.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2013-2015, Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include phy-qcom-ufs-qmp-14nm.h
+
+#define UFS_PHY_NAME ufs_phy_qmp_14nm
+#define UFS_PHY_VDDA_PHY_UV(925000)
+
+static
+int ufs_qcom_phy_qmp_14nm_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
+   bool is_rate_B)
+{
+   int tbl_size_A = ARRAY_SIZE(phy_cal_table_rate_A);
+   int tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B);
+   int err;
+
+   err = ufs_qcom_phy_calibrate(ufs_qcom_phy, phy_cal_table_rate_A,
+   tbl_size_A, phy_cal_table_rate_B, tbl_size_B, is_rate_B);
+
+   if (err)
+   dev_err(ufs_qcom_phy-dev,
+   %s: ufs_qcom_phy_calibrate() failed %d\n,
+   __func__, err);
+   return err;
+}
+
+static
+void ufs_qcom_phy_qmp_14nm_advertise_quirks(struct ufs_qcom_phy *phy_common)
+{
+   phy_common-quirks =
+   UFS_QCOM_PHY_QUIRK_HIBERN8_EXIT_AFTER_PHY_PWR_COLLAPSE;
+}
+
+static int ufs_qcom_phy_qmp_14nm_init(struct phy *generic_phy)
+{
+   struct ufs_qcom_phy_qmp_14nm *phy = phy_get_drvdata(generic_phy);
+   struct ufs_qcom_phy *phy_common = phy-common_cfg;
+   int err;
+
+   err = ufs_qcom_phy_init_clks(generic_phy, phy_common);
+   if (err) {
+   dev_err(phy_common-dev, %s: ufs_qcom_phy_init_clks() failed 
%d\n,
+   __func__, err);
+   goto out;
+   }
+
+   err = ufs_qcom_phy_init_vregulators(generic_phy, phy_common);
+   if (err) {
+   dev_err(phy_common-dev, %s: ufs_qcom_phy_init_vregulators() 
failed %d\n,
+   __func__, err);
+   goto out;
+   }
+   phy_common-vdda_phy.max_uV = UFS_PHY_VDDA_PHY_UV;
+   phy_common-vdda_phy.min_uV = UFS_PHY_VDDA_PHY_UV;
+
+   ufs_qcom_phy_qmp_14nm_advertise_quirks(phy_common);
+
+out:
+   return err;
+}
+
+static
+void ufs_qcom_phy_qmp_14nm_power_control(struct ufs_qcom_phy *phy, bool val)
+{
+   writel_relaxed(val ? 0x1 : 0x0, phy-mmio + UFS_PHY_POWER_DOWN_CONTROL);
+   /*
+* Before any transactions involving PHY, ensure PHY knows
+* that it's analog rail is powered ON (or OFF).
+*/
+   mb();
+}
+
+static inline
+void ufs_qcom_phy_qmp_14nm_set_tx_lane_enable(struct ufs_qcom_phy *phy, u32 
val)
+{
+   /*
+* 14nm PHY does not have TX_LANE_ENABLE register.
+* Implement this function so as not to propagate error to caller.
+*/
+}
+
+static inline void ufs_qcom_phy_qmp_14nm_start_serdes(struct ufs_qcom_phy *phy)
+{
+   u32 tmp;
+
+   tmp = readl_relaxed(phy-mmio + UFS_PHY_PHY_START);
+   tmp = ~MASK_SERDES_START;
+   tmp |= (1  OFFSET_SERDES_START);
+   writel_relaxed(tmp, phy-mmio + UFS_PHY_PHY_START);
+   /* Ensure register value is committed */
+   mb();
+}
+
+static int ufs_qcom_phy_qmp_14nm_is_pcs_ready(struct ufs_qcom_phy *phy_common)
+{
+   int err = 0;
+   u32 val;
+
+   err = readl_poll_timeout(phy_common-mmio + UFS_PHY_PCS_READY_STATUS,
+   val, (val  MASK_PCS_READY), 10, 100);
+   if (err)
+   dev_err(phy_common-dev, %s: poll for pcs failed err = %d\n,
+   __func__, err);
+   return err;
+}
+
+static struct phy_ops