linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/5] exynos-ufs: Add support for UFS HCI
       [not found] <CGME20200327171411epcas5p17f4457f9fd61800257607059b9506fb2@epcas5p1.samsung.com>
@ 2020-03-27 17:06 ` Alim Akhtar
       [not found]   ` <CGME20200327171414epcas5p1460e932c0bc98f31ebdd115218b4fd49@epcas5p1.samsung.com>
                     ` (4 more replies)
  0 siblings, 5 replies; 22+ messages in thread
From: Alim Akhtar @ 2020-03-27 17:06 UTC (permalink / raw)
  To: robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, Alim Akhtar, stanley.chu,
	linux-arm-kernel

This patch-set introduces UFS (Universal Flash Storage) host controller support
for Samsung family SoC. Mostly, it consists of UFS PHY and host specific driver.

- Changes since v3:
* Addressed Kishon's and Avir's review comments
* fixed make dt_binding_check error as pointed by Rob 

- Changes since v2:
* fixed build warning by kbuild test robot 
* Added Reported-by tags

- Changes since v1:
* fixed make dt_binding_check error as pointed by Rob
* Addressed Krzysztof's review comments
* Added Reviewed-by tags

 
patch 1/5: define devicetree bindings for UFS PHY
patch 2/5: Adds UFS PHY driver
patch 3/5: define devicetree bindings for UFS HCI 
patch 4/5: Adds Samsung UFS HCI driver
patch 5/5: Enabled UFS on exynos7 platform

Note: This series is based on Linux-5.6-rc6 (commit: fb33c6510d55)


Alim Akhtar (5):
  dt-bindings: phy: Document Samsung UFS PHY bindings
  phy: samsung-ufs: add UFS PHY driver for samsung SoC
  Documentation: devicetree: ufs: Add DT bindings for exynos UFS host
    controller
  scsi: ufs-exynos: add UFS host support for Exynos SoCs
  arm64: dts: Add node for ufs exynos7

 .../bindings/phy/samsung,ufs-phy.yaml         |   62 +
 .../devicetree/bindings/ufs/ufs-exynos.txt    |  104 ++
 .../boot/dts/exynos/exynos7-espresso.dts      |   16 +
 arch/arm64/boot/dts/exynos/exynos7.dtsi       |   44 +-
 drivers/phy/samsung/Kconfig                   |    9 +
 drivers/phy/samsung/Makefile                  |    1 +
 drivers/phy/samsung/phy-exynos7-ufs.h         |   85 +
 drivers/phy/samsung/phy-samsung-ufs.c         |  311 ++++
 drivers/phy/samsung/phy-samsung-ufs.h         |  100 ++
 drivers/scsi/ufs/Kconfig                      |   12 +
 drivers/scsi/ufs/Makefile                     |    1 +
 drivers/scsi/ufs/ufs-exynos.c                 | 1399 +++++++++++++++++
 drivers/scsi/ufs/ufs-exynos.h                 |  268 ++++
 drivers/scsi/ufs/unipro.h                     |   41 +
 include/linux/phy/phy-samsung-ufs.h           |   70 +
 15 files changed, 2521 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
 create mode 100644 Documentation/devicetree/bindings/ufs/ufs-exynos.txt
 create mode 100644 drivers/phy/samsung/phy-exynos7-ufs.h
 create mode 100644 drivers/phy/samsung/phy-samsung-ufs.c
 create mode 100644 drivers/phy/samsung/phy-samsung-ufs.h
 create mode 100644 drivers/scsi/ufs/ufs-exynos.c
 create mode 100644 drivers/scsi/ufs/ufs-exynos.h
 create mode 100644 include/linux/phy/phy-samsung-ufs.h

-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v4 1/5] dt-bindings: phy: Document Samsung UFS PHY bindings
       [not found]   ` <CGME20200327171414epcas5p1460e932c0bc98f31ebdd115218b4fd49@epcas5p1.samsung.com>
@ 2020-03-27 17:06     ` Alim Akhtar
  2020-04-05  1:54       ` Rob Herring
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-03-27 17:06 UTC (permalink / raw)
  To: robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, Alim Akhtar, stanley.chu,
	linux-arm-kernel

This patch documents Samsung UFS PHY device tree bindings

Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
---
 .../bindings/phy/samsung,ufs-phy.yaml         | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
new file mode 100644
index 000000000000..41ba481ecc76
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/samsung,ufs-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung SoC series UFS PHY Device Tree Bindings
+
+maintainers:
+  - Alim Akhtar <alim.akhtar@samsung.com>
+
+properties:
+  "#phy-cells":
+    const: 0
+
+  compatible:
+    enum:
+      - samsung,exynos7-ufs-phy
+
+  reg:
+    maxItems: 1
+    description: PHY base register address
+
+  reg-names:
+    items:
+      - const: phy-pma
+
+  clocks:
+    items:
+      - description: PLL reference clock
+      - description: Referencec clock parrent
+
+  clock-names:
+    items:
+      - const: ref_clk_parent
+      - const: ref_clk
+
+  samsung,pmu-syscon:
+    $ref: '/schemas/types.yaml#/definitions/phandle'
+    description: phandle for PMU system controller interface, used to
+                 control pmu registers for power isolation
+
+required:
+  - "#phy-cells"
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - samsung,pmu-syscon
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos7-clk.h>
+
+    ufs_phy: ufs-phy@15571800 {
+        compatible = "samsung,exynos7-ufs-phy";
+        reg = <0x15571800 0x240>;
+        reg-names = "phy-pma";
+        samsung,pmu-syscon = <&pmu_system_controller>;
+        #phy-cells = <0>;
+        clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
+                 <&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
+        clock-names = "ref_clk_parent",
+                      "ref_clk";
+    };
+...

base-commit: fb33c6510d5595144d585aa194d377cf74d31911
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 2/5] phy: samsung-ufs: add UFS PHY driver for samsung SoC
       [not found]   ` <CGME20200327171416epcas5p43133a28159ef24b145fcc8f3df102dde@epcas5p4.samsung.com>
@ 2020-03-27 17:06     ` Alim Akhtar
  0 siblings, 0 replies; 22+ messages in thread
From: Alim Akhtar @ 2020-03-27 17:06 UTC (permalink / raw)
  To: robh+dt, devicetree, linux-scsi
  Cc: Kishon Vijay Abraham I, linux-samsung-soc, martin.petersen,
	linux-kernel, krzk, kwmad.kim, avri.altman, cang, Alim Akhtar,
	stanley.chu, linux-arm-kernel

This patch introduces Samsung UFS PHY driver. This driver
supports to deal with phy calibration and power control
according to UFS host driver's behavior.

Reviewed-by: Kiwoong Kim <kwmad.kim@samsung.com>
Signed-off-by: Seungwon Jeon <essuuj@gmail.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/samsung/Kconfig           |   9 +
 drivers/phy/samsung/Makefile          |   1 +
 drivers/phy/samsung/phy-exynos7-ufs.h |  85 +++++++
 drivers/phy/samsung/phy-samsung-ufs.c | 310 ++++++++++++++++++++++++++
 drivers/phy/samsung/phy-samsung-ufs.h | 139 ++++++++++++
 5 files changed, 544 insertions(+)
 create mode 100644 drivers/phy/samsung/phy-exynos7-ufs.h
 create mode 100644 drivers/phy/samsung/phy-samsung-ufs.c
 create mode 100644 drivers/phy/samsung/phy-samsung-ufs.h

diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig
index 9e483d1fdaf2..fc1e3c17f842 100644
--- a/drivers/phy/samsung/Kconfig
+++ b/drivers/phy/samsung/Kconfig
@@ -29,6 +29,15 @@ config PHY_EXYNOS_PCIE
 	  Enable PCIe PHY support for Exynos SoC series.
 	  This driver provides PHY interface for Exynos PCIe controller.
 
+config PHY_SAMSUNG_UFS
+	tristate "SAMSUNG SoC series UFS PHY driver"
+	depends on OF && (ARCH_EXYNOS || COMPILE_TEST)
+	select GENERIC_PHY
+	help
+	  Enable this to support the Samsung UFS PHY driver for
+	  Samsung SoCs. This driver provides the interface for UFS
+	  host controller to do PHY related programming.
+
 config PHY_SAMSUNG_USB2
 	tristate "Samsung USB 2.0 PHY driver"
 	depends on HAS_IOMEM
diff --git a/drivers/phy/samsung/Makefile b/drivers/phy/samsung/Makefile
index db9b1aa0de6e..3959100fe8a2 100644
--- a/drivers/phy/samsung/Makefile
+++ b/drivers/phy/samsung/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)	+= phy-exynos-dp-video.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
 obj-$(CONFIG_PHY_EXYNOS_PCIE)		+= phy-exynos-pcie.o
+obj-$(CONFIG_PHY_SAMSUNG_UFS)		+= phy-samsung-ufs.o
 obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
 phy-exynos-usb2-y			+= phy-samsung-usb2.o
 phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2)	+= phy-exynos4210-usb2.o
diff --git a/drivers/phy/samsung/phy-exynos7-ufs.h b/drivers/phy/samsung/phy-exynos7-ufs.h
new file mode 100644
index 000000000000..da981c1ac040
--- /dev/null
+++ b/drivers/phy/samsung/phy-exynos7-ufs.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * UFS PHY driver data for Samsung EXYNOS7 SoC
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd.
+ */
+#ifndef _PHY_EXYNOS7_UFS_H_
+#define _PHY_EXYNOS7_UFS_H_
+
+#include "phy-samsung-ufs.h"
+
+#define EXYNOS7_EMBEDDED_COMBO_PHY_CTRL	0x720
+#define EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_MASK	0x1
+#define EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_EN	BIT(0)
+
+/* Calibration for phy initialization */
+static const struct samsung_ufs_phy_cfg exynos7_pre_init_cfg[] = {
+	PHY_COMN_REG_CFG(0x00f, 0xfa, PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x010, 0x82, PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x011, 0x1e, PWR_MODE_ANY),
+	PHY_COMN_REG_CFG(0x017, 0x84, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x035, 0x58, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x036, 0x32, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x037, 0x40, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x03b, 0x83, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x042, 0x88, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x043, 0xa6, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x048, 0x74, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x04c, 0x5b, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x04d, 0x83, PWR_MODE_ANY),
+	PHY_TRSV_REG_CFG(0x05c, 0x14, PWR_MODE_ANY),
+	END_UFS_PHY_CFG
+};
+
+static const struct samsung_ufs_phy_cfg exynos7_post_init_cfg[] = {
+	END_UFS_PHY_CFG
+};
+
+/* Calibration for HS mode series A/B */
+static const struct samsung_ufs_phy_cfg exynos7_pre_pwr_hs_cfg[] = {
+	PHY_COMN_REG_CFG(0x00f, 0xfa, PWR_MODE_HS_ANY),
+	PHY_COMN_REG_CFG(0x010, 0x82, PWR_MODE_HS_ANY),
+	PHY_COMN_REG_CFG(0x011, 0x1e, PWR_MODE_HS_ANY),
+	/* Setting order: 1st(0x16, 2nd(0x15) */
+	PHY_COMN_REG_CFG(0x016, 0xff, PWR_MODE_HS_ANY),
+	PHY_COMN_REG_CFG(0x015, 0x80, PWR_MODE_HS_ANY),
+	PHY_COMN_REG_CFG(0x017, 0x94, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG(0x036, 0x32, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG(0x037, 0x43, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG(0x038, 0x3f, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG(0x042, 0x88, PWR_MODE_HS_G2_SER_A),
+	PHY_TRSV_REG_CFG(0x042, 0xbb, PWR_MODE_HS_G2_SER_B),
+	PHY_TRSV_REG_CFG(0x043, 0xa6, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG(0x048, 0x74, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG(0x034, 0x35, PWR_MODE_HS_G2_SER_A),
+	PHY_TRSV_REG_CFG(0x034, 0x36, PWR_MODE_HS_G2_SER_B),
+	PHY_TRSV_REG_CFG(0x035, 0x5b, PWR_MODE_HS_G2_SER_A),
+	PHY_TRSV_REG_CFG(0x035, 0x5c, PWR_MODE_HS_G2_SER_B),
+	END_UFS_PHY_CFG
+};
+
+/* Calibration for HS mode series A/B atfer PMC */
+static const struct samsung_ufs_phy_cfg exynos7_post_pwr_hs_cfg[] = {
+	PHY_COMN_REG_CFG(0x015, 0x00, PWR_MODE_HS_ANY),
+	PHY_TRSV_REG_CFG(0x04d, 0x83, PWR_MODE_HS_ANY),
+	END_UFS_PHY_CFG
+};
+
+static const struct samsung_ufs_phy_cfg *exynos7_ufs_phy_cfgs[CFG_TAG_MAX] = {
+	[CFG_PRE_INIT]		= exynos7_pre_init_cfg,
+	[CFG_POST_INIT]		= exynos7_post_init_cfg,
+	[CFG_PRE_PWR_HS]	= exynos7_pre_pwr_hs_cfg,
+	[CFG_POST_PWR_HS]	= exynos7_post_pwr_hs_cfg,
+};
+
+static struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
+	.cfg = exynos7_ufs_phy_cfgs,
+	.isol = {
+		.offset = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL,
+		.mask = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_MASK,
+		.en = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_EN,
+	},
+};
+
+#endif /* _PHY_EXYNOS7_UFS_H_ */
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
new file mode 100644
index 000000000000..572e40e72776
--- /dev/null
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UFS PHY driver for Samsung SoC
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd.
+ * Author: Seungwon Jeon <essuuj@gmail.com>
+ * Author: Alim Akhtar <alim.akhtar@samsung.com>
+ *
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "phy-samsung-ufs.h"
+
+#define for_each_phy_lane(phy, i) \
+	for (i = 0; i < (phy)->lane_cnt; i++)
+#define for_each_phy_cfg(cfg) \
+	for (; (cfg)->id; (cfg)++)
+
+#define PHY_DEF_LANE_CNT	1
+
+static void samsung_ufs_phy_config(struct samsung_ufs_phy *phy,
+			const struct samsung_ufs_phy_cfg *cfg, u8 lane)
+{
+	enum {LANE_0, LANE_1}; /* lane index */
+
+	switch (lane) {
+	case LANE_0:
+		writel(cfg->val, (phy)->reg_pma + cfg->off_0);
+		break;
+	case LANE_1:
+		if (cfg->id == PHY_TRSV_BLK)
+			writel(cfg->val, (phy)->reg_pma + cfg->off_1);
+		break;
+	}
+}
+
+int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy)
+{
+	struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
+	const unsigned int timeout_us = 100000;
+	const unsigned int sleep_us = 10;
+	u32 val;
+	int err;
+
+	err = readl_poll_timeout(
+			ufs_phy->reg_pma + PHY_APB_ADDR(PHY_PLL_LOCK_STATUS),
+			val, (val & PHY_PLL_LOCK_BIT), sleep_us, timeout_us);
+	if (err) {
+		dev_err(ufs_phy->dev,
+			"failed to get phy pll lock acquisition %d\n", err);
+		goto out;
+	}
+
+	err = readl_poll_timeout(
+			ufs_phy->reg_pma + PHY_APB_ADDR(PHY_CDR_LOCK_STATUS),
+			val, (val & PHY_CDR_LOCK_BIT), sleep_us, timeout_us);
+	if (err) {
+		dev_err(ufs_phy->dev,
+			"failed to get phy cdr lock acquisition %d\n", err);
+		goto out;
+	}
+
+out:
+	return err;
+}
+
+int samsung_ufs_phy_calibrate(struct phy *phy)
+{
+	struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
+	struct samsung_ufs_phy_cfg **cfgs = ufs_phy->cfg;
+	const struct samsung_ufs_phy_cfg *cfg;
+	int i;
+	int err = 0;
+
+	if (unlikely(ufs_phy->ufs_phy_state < CFG_PRE_INIT ||
+		     ufs_phy->ufs_phy_state >= CFG_TAG_MAX)) {
+		dev_err(ufs_phy->dev, "invalid phy config index %d\n",
+							ufs_phy->ufs_phy_state);
+		return -EINVAL;
+	}
+
+	if (ufs_phy->is_pre_init)
+		ufs_phy->is_pre_init = false;
+	if (ufs_phy->is_post_init) {
+		ufs_phy->is_post_init = false;
+		ufs_phy->ufs_phy_state = CFG_POST_INIT;
+	}
+	if (ufs_phy->is_pre_pmc) {
+		ufs_phy->is_pre_pmc = false;
+		ufs_phy->ufs_phy_state = CFG_PRE_PWR_HS;
+	}
+	if (ufs_phy->is_post_pmc) {
+		ufs_phy->is_post_pmc = false;
+		ufs_phy->ufs_phy_state = CFG_POST_PWR_HS;
+	}
+
+	switch (ufs_phy->ufs_phy_state) {
+	case CFG_PRE_INIT:
+		ufs_phy->is_post_init = true;
+		break;
+	case CFG_POST_INIT:
+		ufs_phy->is_pre_pmc = true;
+		break;
+	case CFG_PRE_PWR_HS:
+		ufs_phy->is_post_pmc = true;
+		break;
+	case CFG_POST_PWR_HS:
+		break;
+	default:
+		dev_err(ufs_phy->dev, "wrong state for phy calibration\n");
+	}
+
+	cfg = cfgs[ufs_phy->ufs_phy_state];
+	if (!cfg)
+		goto out;
+
+	for_each_phy_cfg(cfg) {
+		for_each_phy_lane(ufs_phy, i) {
+			samsung_ufs_phy_config(ufs_phy, cfg, i);
+		}
+	}
+
+	if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS)
+		err = samsung_ufs_phy_wait_for_lock_acq(phy);
+out:
+	return err;
+}
+
+static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy)
+{
+	struct clk *child, *parent;
+
+	child = devm_clk_get(phy->dev, "ref_clk");
+	if (IS_ERR(child))
+		dev_err(phy->dev, "failed to get ref_clk clock\n");
+	else
+		phy->ref_clk = child;
+
+	parent = devm_clk_get(phy->dev, "ref_clk_parent");
+	if (IS_ERR(parent))
+		dev_err(phy->dev, "failed to get ref_clk_parent clock\n");
+	else
+		phy->ref_clk_parent = parent;
+
+	return clk_set_parent(child, parent);
+}
+
+static int samsung_ufs_phy_init(struct phy *phy)
+{
+	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy);
+
+	_phy->lane_cnt = phy->attrs.bus_width;
+	_phy->ufs_phy_state = CFG_PRE_INIT;
+
+	_phy->is_pre_init = true;
+	_phy->is_post_init = false;
+	_phy->is_pre_pmc = false;
+	_phy->is_post_pmc = false;
+
+	samsung_ufs_phy_clks_init(_phy);
+
+	samsung_ufs_phy_calibrate(phy);
+
+	return 0;
+}
+
+static int samsung_ufs_phy_power_on(struct phy *phy)
+{
+	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy);
+	int ret;
+
+	ret = clk_prepare_enable(_phy->ref_clk);
+	if (ret) {
+		dev_err(_phy->dev, "%s: ref_clk enable failed %d\n",
+				__func__, ret);
+		return ret;
+	}
+
+	samsung_ufs_phy_ctrl_isol(_phy, false);
+	return 0;
+}
+
+static int samsung_ufs_phy_power_off(struct phy *phy)
+{
+	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy);
+
+	samsung_ufs_phy_ctrl_isol(_phy, true);
+	clk_disable_unprepare(_phy->ref_clk);
+	return 0;
+}
+
+static int samsung_ufs_phy_set_mode(struct phy *generic_phy,
+					enum phy_mode mode, int submode)
+{
+	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(generic_phy);
+
+	_phy->mode = PHY_MODE_INVALID;
+
+	if (mode > 0)
+		_phy->mode = mode;
+
+	return 0;
+}
+
+static struct phy_ops samsung_ufs_phy_ops = {
+	.init		= samsung_ufs_phy_init,
+	.power_on	= samsung_ufs_phy_power_on,
+	.power_off	= samsung_ufs_phy_power_off,
+	.calibrate	= samsung_ufs_phy_calibrate,
+	.set_mode	= samsung_ufs_phy_set_mode,
+}
+;
+static const struct of_device_id samsung_ufs_phy_match[];
+
+static int samsung_ufs_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	const struct of_device_id *match;
+	struct samsung_ufs_phy *phy;
+	struct phy *gen_phy;
+	struct phy_provider *phy_provider;
+	const struct samsung_ufs_phy_drvdata *drvdata;
+	int err = 0;
+
+	match = of_match_node(samsung_ufs_phy_match, dev->of_node);
+	if (!match) {
+		err = -EINVAL;
+		dev_err(dev, "failed to get match_node\n");
+		goto out;
+	}
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy-pma");
+	phy->reg_pma = devm_ioremap_resource(dev, res);
+	if (IS_ERR(phy->reg_pma)) {
+		err = PTR_ERR(phy->reg_pma);
+		goto out;
+	}
+
+	phy->reg_pmu = syscon_regmap_lookup_by_phandle(
+				dev->of_node, "samsung,pmu-syscon");
+	if (IS_ERR(phy->reg_pmu)) {
+		err = PTR_ERR(phy->reg_pmu);
+		dev_err(dev, "failed syscon remap for pmu\n");
+		goto out;
+	}
+
+	gen_phy = devm_phy_create(dev, NULL, &samsung_ufs_phy_ops);
+	if (IS_ERR(gen_phy)) {
+		err = PTR_ERR(gen_phy);
+		dev_err(dev, "failed to create PHY for ufs-phy\n");
+		goto out;
+	}
+
+	drvdata = match->data;
+	phy->dev = dev;
+	phy->drvdata = drvdata;
+	phy->cfg = (struct samsung_ufs_phy_cfg **)drvdata->cfg;
+	phy->isol = &drvdata->isol;
+	phy->lane_cnt = PHY_DEF_LANE_CNT;
+
+	phy_set_drvdata(gen_phy, phy);
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		err = PTR_ERR(phy_provider);
+		dev_err(dev, "failed to register phy-provider\n");
+		goto out;
+	}
+out:
+	return err;
+}
+
+static const struct of_device_id samsung_ufs_phy_match[] = {
+	{
+		.compatible = "samsung,exynos7-ufs-phy",
+		.data = &exynos7_ufs_phy,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, samsung_ufs_phy_match);
+
+static struct platform_driver samsung_ufs_phy_driver = {
+	.probe  = samsung_ufs_phy_probe,
+	.driver = {
+		.name = "samsung-ufs-phy",
+		.of_match_table = samsung_ufs_phy_match,
+	},
+};
+module_platform_driver(samsung_ufs_phy_driver);
+MODULE_DESCRIPTION("Samsung SoC UFS PHY Driver");
+MODULE_AUTHOR("Seungwon Jeon <essuuj@gmail.com>");
+MODULE_AUTHOR("Alim Akhtar <alim.akhtar@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/phy/samsung/phy-samsung-ufs.h b/drivers/phy/samsung/phy-samsung-ufs.h
new file mode 100644
index 000000000000..971d67ae7f80
--- /dev/null
+++ b/drivers/phy/samsung/phy-samsung-ufs.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * UFS PHY driver for Samsung EXYNOS SoC
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd.
+ * Author: Seungwon Jeon <essuuj@gmail.com>
+ * Author: Alim Akhtar <alim.akhtar@samsung.com>
+ *
+ */
+#ifndef _PHY_SAMSUNG_UFS_
+#define _PHY_SAMSUNG_UFS_
+
+#define PHY_COMN_BLK	1
+#define PHY_TRSV_BLK	2
+#define END_UFS_PHY_CFG { 0 }
+#define PHY_TRSV_CH_OFFSET	0x30
+#define PHY_APB_ADDR(off)	((off) << 2)
+
+#define PHY_COMN_REG_CFG(o, v, d) {	\
+	.off_0 = PHY_APB_ADDR((o)),	\
+	.off_1 = 0,		\
+	.val = (v),		\
+	.desc = (d),		\
+	.id = PHY_COMN_BLK,	\
+}
+
+#define PHY_TRSV_REG_CFG(o, v, d) {	\
+	.off_0 = PHY_APB_ADDR((o)),	\
+	.off_1 = PHY_APB_ADDR((o) + PHY_TRSV_CH_OFFSET),	\
+	.val = (v),		\
+	.desc = (d),		\
+	.id = PHY_TRSV_BLK,	\
+}
+
+/* UFS PHY registers */
+#define PHY_PLL_LOCK_STATUS	0x1e
+#define PHY_CDR_LOCK_STATUS	0x5e
+
+#define PHY_PLL_LOCK_BIT	BIT(5)
+#define PHY_CDR_LOCK_BIT	BIT(4)
+
+/* description for PHY calibration */
+enum {
+	/* applicable to any */
+	PWR_DESC_ANY	= 0,
+	/* mode */
+	PWR_DESC_PWM	= 1,
+	PWR_DESC_HS	= 2,
+	/* series */
+	PWR_DESC_SER_A	= 1,
+	PWR_DESC_SER_B	= 2,
+	/* gear */
+	PWR_DESC_G1	= 1,
+	PWR_DESC_G2	= 2,
+	PWR_DESC_G3	= 3,
+	/* field mask */
+	MD_MASK		= 0x3,
+	SR_MASK		= 0x3,
+	GR_MASK		= 0x7,
+};
+
+#define PWR_MODE_HS_G1_ANY	PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_ANY)
+#define PWR_MODE_HS_G1_SER_A	PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_A)
+#define PWR_MODE_HS_G1_SER_B	PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_B)
+#define PWR_MODE_HS_G2_ANY	PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_ANY)
+#define PWR_MODE_HS_G2_SER_A	PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_A)
+#define PWR_MODE_HS_G2_SER_B	PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_B)
+#define PWR_MODE_HS_G3_ANY	PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_ANY)
+#define PWR_MODE_HS_G3_SER_A	PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_A)
+#define PWR_MODE_HS_G3_SER_B	PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_B)
+#define PWR_MODE(g, s, m)	((((g) & GR_MASK) << 4) |\
+				 (((s) & SR_MASK) << 2) | ((m) & MD_MASK))
+#define PWR_MODE_PWM_ANY	PWR_MODE(PWR_DESC_ANY,\
+					 PWR_DESC_ANY, PWR_DESC_PWM)
+#define PWR_MODE_HS(g, s)	((((g) & GR_MASK) << 4) |\
+				 (((s) & SR_MASK) << 2) | PWR_DESC_HS)
+#define PWR_MODE_HS_ANY		PWR_MODE(PWR_DESC_ANY,\
+					 PWR_DESC_ANY, PWR_DESC_HS)
+#define PWR_MODE_ANY		PWR_MODE(PWR_DESC_ANY,\
+					 PWR_DESC_ANY, PWR_DESC_ANY)
+/* PHY calibration point/state */
+enum {
+	CFG_PRE_INIT,
+	CFG_POST_INIT,
+	CFG_PRE_PWR_HS,
+	CFG_POST_PWR_HS,
+	CFG_TAG_MAX,
+};
+
+struct samsung_ufs_phy_cfg {
+	u32 off_0;
+	u32 off_1;
+	u32 val;
+	u8 desc;
+	u8 id;
+};
+
+struct samsung_ufs_phy_drvdata {
+	const struct samsung_ufs_phy_cfg **cfg;
+	struct pmu_isol {
+		u32 offset;
+		u32 mask;
+		u32 en;
+	} isol;
+};
+
+struct samsung_ufs_phy {
+	struct device *dev;
+	void __iomem *reg_pma;
+	struct regmap *reg_pmu;
+	struct clk *ref_clk;
+	struct clk *ref_clk_parent;
+	const struct samsung_ufs_phy_drvdata *drvdata;
+	struct samsung_ufs_phy_cfg **cfg;
+	const struct pmu_isol *isol;
+	u8 lane_cnt;
+	int ufs_phy_state;
+	enum phy_mode mode;
+	bool is_pre_init;
+	bool is_post_init;
+	bool is_pre_pmc;
+	bool is_post_pmc;
+};
+
+static inline struct samsung_ufs_phy *get_samsung_ufs_phy(struct phy *phy)
+{
+	return (struct samsung_ufs_phy *)phy_get_drvdata(phy);
+}
+
+static inline void samsung_ufs_phy_ctrl_isol(
+		struct samsung_ufs_phy *phy, u32 isol)
+{
+	regmap_update_bits(phy->reg_pmu, phy->isol->offset,
+			phy->isol->mask, isol ? 0 : phy->isol->en);
+}
+
+#include "phy-exynos7-ufs.h"
+
+#endif /* _PHY_SAMSUNG_UFS_ */
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 3/5] Documentation: devicetree: ufs: Add DT bindings for exynos UFS host controller
       [not found]   ` <CGME20200327171418epcas5p4b85bea273e17c05a7edca58f528c435a@epcas5p4.samsung.com>
@ 2020-03-27 17:06     ` Alim Akhtar
  2020-04-05  2:02       ` Rob Herring
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-03-27 17:06 UTC (permalink / raw)
  To: robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, Alim Akhtar, stanley.chu,
	linux-arm-kernel

This adds Exynos Universal Flash Storage (UFS) Host Controller DT bindings.

Signed-off-by: Seungwon Jeon <essuuj@gmail.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
---
 .../devicetree/bindings/ufs/ufs-exynos.txt    | 104 ++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/ufs/ufs-exynos.txt

diff --git a/Documentation/devicetree/bindings/ufs/ufs-exynos.txt b/Documentation/devicetree/bindings/ufs/ufs-exynos.txt
new file mode 100644
index 000000000000..08e2d1497b1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/ufs/ufs-exynos.txt
@@ -0,0 +1,104 @@
+* Exynos Universal Flash Storage (UFS) Host Controller
+
+UFSHC nodes are defined to describe on-chip UFS host controllers.
+Each UFS controller instance should have its own node.
+
+Required properties:
+- compatible        : compatible name, contains "samsung,exynos7-ufs"
+- interrupts        : <interrupt mapping for UFS host controller IRQ>
+- reg               : Should contain HCI, vendor specific, UNIPRO and
+		      UFS protector address space
+- reg-names	    : "hci", "vs_hci", "unipro", "ufsp";
+
+Optional properties:
+- vdd-hba-supply        : phandle to UFS host controller supply regulator node
+- vcc-supply            : phandle to VCC supply regulator node
+- vccq-supply           : phandle to VCCQ supply regulator node
+- vccq2-supply          : phandle to VCCQ2 supply regulator node
+- vcc-supply-1p8        : For embedded UFS devices, valid VCC range is 1.7-1.95V
+                          or 2.7-3.6V. This boolean property when set, specifies
+			  to use low voltage range of 1.7-1.95V. Note for external
+			  UFS cards this property is invalid and valid VCC range is
+			  always 2.7-3.6V.
+- vcc-max-microamp      : specifies max. load that can be drawn from vcc supply
+- vccq-max-microamp     : specifies max. load that can be drawn from vccq supply
+- vccq2-max-microamp    : specifies max. load that can be drawn from vccq2 supply
+- <name>-fixed-regulator : boolean property specifying that <name>-supply is a fixed regulator
+
+- clocks                : List of phandle and clock specifier pairs
+- clock-names           : List of clock input name strings sorted in the same
+                          order as the clocks property.
+			  "core", "sclk_unipro_main", "ref" and ref_parent
+
+- freq-table-hz		: Array of <min max> operating frequencies stored in the same
+			  order as the clocks property. If this property is not
+			  defined or a value in the array is "0" then it is assumed
+			  that the frequency is set by the parent clock or a
+			  fixed rate clock source.
+- pclk-freq-avail-range : specifies available frequency range(min/max) for APB clock
+- ufs,pwr-attr-mode : specifies mode value for power mode change, possible values are
+			"FAST", "SLOW", "FAST_auto" and "SLOW_auto"
+- ufs,pwr-attr-lane : specifies lane count value for power mode change
+		      allowed values are 1 or 2
+- ufs,pwr-attr-gear : specifies gear count value for power mode change
+		      allowed values are 1 or 2
+- ufs,pwr-attr-hs-series : specifies HS rate series for power mode change
+			   can be one of "HS_rate_b" or "HS_rate_a"
+- ufs,pwr-local-l2-timer : specifies array of local UNIPRO L2 timer values
+			   3 timers supported
+			   <FC0ProtectionTimeOutVal,TC0ReplayTimeOutVal, AFC0ReqTimeOutVal>
+- ufs,pwr-remote-l2-timer : specifies array of remote UNIPRO L2 timer values
+			   3 timers supported
+			   <FC0ProtectionTimeOutVal,TC0ReplayTimeOutVal, AFC0ReqTimeOutVal>
+- ufs-rx-adv-fine-gran-sup_en : specifies support of fine granularity of MPHY,
+			      this is a boolean property.
+- ufs-rx-adv-fine-gran-step : specifies granularity steps of MPHY,
+			      allowed step size is 0 to 3
+- ufs-rx-adv-min-activate-time-cap : specifies rx advanced minimum activate time of MPHY
+				     range is 1 to 9
+- ufs-pa-granularity : specifies Granularity for PA_TActivate and PA_Hibern8Time
+- ufs-pa-tacctivate : specifies time to wake-up remote M-RX
+- ufs-pa-hibern8time : specifies minimum time to wait in HIBERN8 state
+
+Note: If above properties are not defined it can be assumed that the supply
+regulators or clocks are always on.
+
+Example:
+	ufshc@0x15570000 {
+		compatible = "samsung,exynos7-ufs";
+		reg = <0x15570000 0x100>,
+		      <0x15570100 0x100>,
+		      <0x15571000 0x200>,
+		      <0x15572000 0x300>;
+		reg-names = "hci", "vs_hci", "unipro", "ufsp";
+		interrupts = <0 200 0>;
+
+		vdd-hba-supply = <&xxx_reg0>;
+		vdd-hba-fixed-regulator;
+		vcc-supply = <&xxx_reg1>;
+		vcc-supply-1p8;
+		vccq-supply = <&xxx_reg2>;
+		vccq2-supply = <&xxx_reg3>;
+		vcc-max-microamp = 500000;
+		vccq-max-microamp = 200000;
+		vccq2-max-microamp = 200000;
+
+		clocks = <&core 0>, <&ref 0>, <&iface 0>;
+		clock-names = "core", "sclk_unipro_main", "ref", "ref_parent";
+		freq-table-hz = <100000000 200000000>, <0 0>, <0 0>, <0 0>;
+
+		pclk-freq-avail-range = <70000000 133000000>;
+
+		ufs,pwr-attr-mode = "FAST";
+		ufs,pwr-attr-lane = <2>;
+		ufs,pwr-attr-gear = <2>;
+		ufs,pwr-attr-hs-series = "HS_rate_b";
+		ufs,pwr-local-l2-timer = <8000 28000 20000>;
+		ufs,pwr-remote-l2-timer = <12000 32000 16000>;
+		ufs-rx-adv-fine-gran-sup_en = <1>;
+		ufs-rx-adv-fine-gran-step = <3>;
+		ufs-rx-adv-min-activate-time-cap = <9>;
+		ufs-pa-granularity = <6>;
+		ufs-pa-tacctivate = <6>;
+		ufs-pa-hibern8time = <20>;
+	};
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 4/5] scsi: ufs-exynos: add UFS host support for Exynos SoCs
       [not found]   ` <CGME20200327171420epcas5p490e1e6d090a540eaf050e0728a39ba25@epcas5p4.samsung.com>
@ 2020-03-27 17:06     ` Alim Akhtar
  2020-03-28 11:28       ` Avri Altman
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-03-27 17:06 UTC (permalink / raw)
  To: robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, Alim Akhtar, stanley.chu,
	linux-arm-kernel

This patch introduces Exynos UFS host controller driver,
which mainly handles vendor-specific operations including
link startup, power mode change and hibernation/unhibernation.

Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Julia Lawall <julia.lawall@lip6.fr>
[robot: drivers/scsi/ufs/ufs-exynos.c:931:8-10:
 WARNING: possible condition with no effect (if == else)
]
Reviewed-by: Kiwoong Kim <kwmad.kim@samsung.com>
Signed-off-by: Seungwon Jeon <essuuj@gmail.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
---
 drivers/scsi/ufs/Kconfig      |   12 +
 drivers/scsi/ufs/Makefile     |    1 +
 drivers/scsi/ufs/ufs-exynos.c | 1400 +++++++++++++++++++++++++++++++++
 drivers/scsi/ufs/ufs-exynos.h |  268 +++++++
 drivers/scsi/ufs/unipro.h     |   41 +
 5 files changed, 1722 insertions(+)
 create mode 100644 drivers/scsi/ufs/ufs-exynos.c
 create mode 100644 drivers/scsi/ufs/ufs-exynos.h

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index d14c2243e02a..d1b521165cb1 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -160,3 +160,15 @@ config SCSI_UFS_BSG
 
 	  Select this if you need a bsg device node for your UFS controller.
 	  If unsure, say N.
+
+config SCSI_UFS_EXYNOS
+	bool "EXYNOS specific hooks to UFS controller platform driver"
+	depends on SCSI_UFSHCD_PLATFORM && ARCH_EXYNOS || COMPILE_TEST
+	select PHY_SAMSUNG_UFS
+	help
+	  This selects the EXYNOS specific additions to UFSHCD platform driver.
+	  UFS host on EXYNOS includes HCI and UNIPRO layer, and associates with
+	  UFS-PHY driver.
+
+	  Select this if you have UFS host controller on EXYNOS chipset.
+	  If unsure, say N.
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 94c6c5d7334b..ca1d2a130ff6 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -3,6 +3,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_CDNS_PLATFORM) += cdns-pltfrm.o
+obj-$(CONFIG_SCSI_UFS_EXYNOS) += ufs-exynos.o
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
 ufshcd-core-y				+= ufshcd.o ufs-sysfs.o
diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
new file mode 100644
index 000000000000..36171527c225
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-exynos.c
@@ -0,0 +1,1400 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UFS Host Controller driver for Exynos specific extensions
+ *
+ * Copyright (C) 2014-2015 Samsung Electronics Co., Ltd.
+ * Author: Seungwon Jeon  <essuuj@gmail.com>
+ * Author: Alim Akhtar <alim.akhtar@samsung.com>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+#include "ufshcd.h"
+#include "ufshcd-pltfrm.h"
+#include "ufshci.h"
+#include "unipro.h"
+
+#include "ufs-exynos.h"
+
+/*
+ * Exynos's Vendor specific registers for UFSHCI
+ */
+#define HCI_TXPRDT_ENTRY_SIZE	0x00
+#define PRDT_PREFECT_EN		BIT(31)
+#define PRDT_SET_SIZE(x)	((x) & 0x1F)
+#define HCI_RXPRDT_ENTRY_SIZE	0x04
+#define HCI_1US_TO_CNT_VAL	0x0C
+#define CNT_VAL_1US_MASK	0x3FF
+#define HCI_UTRL_NEXUS_TYPE	0x40
+#define HCI_UTMRL_NEXUS_TYPE	0x44
+#define HCI_SW_RST		0x50
+#define UFS_LINK_SW_RST		BIT(0)
+#define UFS_UNIPRO_SW_RST	BIT(1)
+#define UFS_SW_RST_MASK		(UFS_UNIPRO_SW_RST | UFS_LINK_SW_RST)
+#define HCI_DATA_REORDER	0x60
+#define HCI_UNIPRO_APB_CLK_CTRL	0x68
+#define UNIPRO_APB_CLK(v, x)	(((v) & ~0xF) | ((x) & 0xF))
+#define HCI_AXIDMA_RWDATA_BURST_LEN	0x6C
+#define HCI_GPIO_OUT		0x70
+#define HCI_ERR_EN_PA_LAYER	0x78
+#define HCI_ERR_EN_DL_LAYER	0x7C
+#define HCI_ERR_EN_N_LAYER	0x80
+#define HCI_ERR_EN_T_LAYER	0x84
+#define HCI_ERR_EN_DME_LAYER	0x88
+#define HCI_CLKSTOP_CTRL	0xB0
+#define REFCLK_STOP		BIT(2)
+#define UNIPRO_MCLK_STOP	BIT(1)
+#define UNIPRO_PCLK_STOP	BIT(0)
+#define CLK_STOP_MASK		(REFCLK_STOP |\
+				 UNIPRO_MCLK_STOP |\
+				 UNIPRO_PCLK_STOP)
+#define HCI_MISC		0xB4
+#define REFCLK_CTRL_EN		BIT(7)
+#define UNIPRO_PCLK_CTRL_EN	BIT(6)
+#define UNIPRO_MCLK_CTRL_EN	BIT(5)
+#define HCI_CORECLK_CTRL_EN	BIT(4)
+#define CLK_CTRL_EN_MASK	(REFCLK_CTRL_EN |\
+				 UNIPRO_PCLK_CTRL_EN |\
+				 UNIPRO_MCLK_CTRL_EN)
+/* Device fatal error */
+#define DFES_ERR_EN		BIT(31)
+#define DFES_DEF_L2_ERRS	(UIC_DATA_LINK_LAYER_ERROR_RX_BUF_OF |\
+				 UIC_DATA_LINK_LAYER_ERROR_PA_INIT)
+#define DFES_DEF_L3_ERRS	(UIC_NETWORK_UNSUPPORTED_HEADER_TYPE |\
+				 UIC_NETWORK_BAD_DEVICEID_ENC |\
+				 UIC_NETWORK_LHDR_TRAP_PACKET_DROPPING)
+#define DFES_DEF_L4_ERRS	(UIC_TRANSPORT_UNSUPPORTED_HEADER_TYPE |\
+				 UIC_TRANSPORT_UNKNOWN_CPORTID |\
+				 UIC_TRANSPORT_NO_CONNECTION_RX |\
+				 UIC_TRANSPORT_BAD_TC)
+
+/* for calculating Interrupt Aggregation Timeout Value*/
+#define CNTR_DIV_VAL	40
+
+enum {
+	UNIPRO_L1_5 = 0,/* PHY Adapter */
+	UNIPRO_L2,	/* Data Link */
+	UNIPRO_L3,	/* Network */
+	UNIPRO_L4,	/* Transport */
+	UNIPRO_DME,	/* DME */
+};
+
+/*
+ * UNIPRO registers
+ */
+#define UNIPRO_COMP_VERSION			0x000
+#define UNIPRO_DME_PWR_REQ			0x090
+#define UNIPRO_DME_PWR_REQ_POWERMODE		0x094
+#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER0	0x098
+#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER1	0x09C
+#define UNIPRO_DME_PWR_REQ_LOCALL2TIMER2	0x0A0
+#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER0	0x0A4
+#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER1	0x0A8
+#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER2	0x0AC
+
+/*
+ * UFS Protector registers
+ */
+#define UFSPRSECURITY	0x010
+#define NSSMU		BIT(14)
+#define UFSPSBEGIN0	0x200
+#define UFSPSEND0	0x204
+#define UFSPSLUN0	0x208
+#define UFSPSCTRL0	0x20C
+
+static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en);
+static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en);
+
+static inline void exynos_ufs_enable_auto_ctrl_hcc(struct exynos_ufs *ufs)
+{
+	exynos_ufs_auto_ctrl_hcc(ufs, true);
+}
+
+static inline void exynos_ufs_disable_auto_ctrl_hcc(struct exynos_ufs *ufs)
+{
+	exynos_ufs_auto_ctrl_hcc(ufs, false);
+}
+
+static inline void exynos_ufs_disable_auto_ctrl_hcc_save(
+					struct exynos_ufs *ufs, u32 *val)
+{
+	*val = hci_readl(ufs, HCI_MISC);
+	exynos_ufs_auto_ctrl_hcc(ufs, false);
+}
+
+static inline void exynos_ufs_auto_ctrl_hcc_restore(
+					struct exynos_ufs *ufs, u32 *val)
+{
+	hci_writel(ufs, *val, HCI_MISC);
+}
+
+static inline void exynos_ufs_gate_clks(struct exynos_ufs *ufs)
+{
+	exynos_ufs_ctrl_clkstop(ufs, true);
+}
+
+static inline void exynos_ufs_ungate_clks(struct exynos_ufs *ufs)
+{
+	exynos_ufs_ctrl_clkstop(ufs, false);
+}
+
+static int exynos7_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs)
+{
+	return 0;
+}
+
+static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	u32 val = ufs->drv_data->uic_attr->pa_dbg_option_suite;
+	int i;
+
+	exynos_ufs_enable_ov_tm(hba);
+	for_each_ufs_tx_lane(ufs, i)
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x297, i), 0x17);
+	for_each_ufs_rx_lane(ufs, i) {
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x362, i), 0xff);
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x363, i), 0x00);
+	}
+	exynos_ufs_disable_ov_tm(hba);
+
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE_DYN), 0xf);
+	for_each_ufs_tx_lane(ufs, i)
+		ufshcd_dme_set(hba,
+			UIC_ARG_MIB_SEL(TX_HIBERN8_CONTROL, i), 0x0);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_TXPHY_CFGUPDT), 0x1);
+	udelay(1);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val | (1 << 12));
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_RESET_PHY), 0x1);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_LINE_RESET), 0x1);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_LINE_RESET_REQ), 0x1);
+	udelay(1600);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val);
+
+	return 0;
+}
+
+static int exynos7_ufs_post_link(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	int i;
+
+	exynos_ufs_enable_ov_tm(hba);
+	for_each_ufs_tx_lane(ufs, i) {
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x28b, i), 0x83);
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x29a, i), 0x07);
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x277, i),
+			TX_LINERESET_N(exynos_ufs_calc_time_cntr(ufs, 200000)));
+	}
+	exynos_ufs_disable_ov_tm(hba);
+
+	exynos_ufs_enable_dbg_mode(hba);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_SAVECONFIGTIME), 0xbb8);
+	exynos_ufs_disable_dbg_mode(hba);
+
+	return 0;
+}
+
+static int exynos7_ufs_pre_pwr_change(struct exynos_ufs *ufs,
+						struct uic_pwr_mode *pwr)
+{
+	unipro_writel(ufs, 0x22, UNIPRO_DBG_FORCE_DME_CTRL_STATE);
+
+	return 0;
+}
+
+static int exynos7_ufs_post_pwr_change(struct exynos_ufs *ufs,
+						struct uic_pwr_mode *pwr)
+{
+	struct ufs_hba *hba = ufs->hba;
+
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_RXPHY_CFGUPDT), 0x1);
+
+	if (pwr->lane == 1) {
+		exynos_ufs_enable_dbg_mode(hba);
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), 0x1);
+		exynos_ufs_disable_dbg_mode(hba);
+	}
+
+	return 0;
+}
+
+/**
+ * exynos_ufs_auto_ctrl_hcc - HCI core clock control by h/w
+ * Control should be disabled in the below cases
+ * - Before host controller S/W reset
+ * - Access to UFS protector's register
+ */
+static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en)
+{
+	u32 misc = hci_readl(ufs, HCI_MISC);
+
+	if (en)
+		hci_writel(ufs, misc | HCI_CORECLK_CTRL_EN, HCI_MISC);
+	else
+		hci_writel(ufs, misc & ~HCI_CORECLK_CTRL_EN, HCI_MISC);
+}
+
+static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en)
+{
+	u32 ctrl = hci_readl(ufs, HCI_CLKSTOP_CTRL);
+	u32 misc = hci_readl(ufs, HCI_MISC);
+
+	if (en) {
+		hci_writel(ufs, misc | CLK_CTRL_EN_MASK, HCI_MISC);
+		hci_writel(ufs, ctrl | CLK_STOP_MASK, HCI_CLKSTOP_CTRL);
+	} else {
+		hci_writel(ufs, ctrl & ~CLK_STOP_MASK, HCI_CLKSTOP_CTRL);
+		hci_writel(ufs, misc & ~CLK_CTRL_EN_MASK, HCI_MISC);
+	}
+}
+
+static int exynos_ufs_get_clk_info(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	struct list_head *head = &hba->clk_list_head;
+	struct ufs_clk_info *clki;
+	u32 pclk_rate;
+	u32 f_min, f_max;
+	u8 div = 0;
+	int ret = 0;
+
+	if (!head || list_empty(head))
+		goto out;
+
+	list_for_each_entry(clki, head, list) {
+		if (!IS_ERR(clki->clk)) {
+			if (!strcmp(clki->name, "core_clk"))
+				ufs->clk_hci_core = clki->clk;
+			else if (!strcmp(clki->name, "sclk_unipro_main"))
+				ufs->clk_unipro_main = clki->clk;
+		}
+	}
+
+	if (!ufs->clk_hci_core || !ufs->clk_unipro_main) {
+		dev_err(hba->dev, "failed to get clk info\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ufs->mclk_rate = clk_get_rate(ufs->clk_unipro_main);
+	pclk_rate = clk_get_rate(ufs->clk_hci_core);
+	f_min = ufs->pclk_avail_min;
+	f_max = ufs->pclk_avail_max;
+
+	if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) {
+		do {
+			pclk_rate /= (div + 1);
+
+			if (pclk_rate <= f_max)
+				break;
+			div++;
+		} while (pclk_rate >= f_min);
+	}
+
+	if (unlikely(pclk_rate < f_min || pclk_rate > f_max)) {
+		dev_err(hba->dev, "not available pclk range %d\n", pclk_rate);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ufs->pclk_rate = pclk_rate;
+	ufs->pclk_div = div;
+
+out:
+	return ret;
+}
+
+static void exynos_ufs_set_unipro_pclk_div(struct exynos_ufs *ufs)
+{
+	if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) {
+		u32 val;
+
+		val = hci_readl(ufs, HCI_UNIPRO_APB_CLK_CTRL);
+		hci_writel(ufs, UNIPRO_APB_CLK(val, ufs->pclk_div),
+			   HCI_UNIPRO_APB_CLK_CTRL);
+	}
+}
+
+static void exynos_ufs_set_pwm_clk_div(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
+
+	ufshcd_dme_set(hba,
+		UIC_ARG_MIB(CMN_PWM_CLK_CTRL), attr->cmn_pwm_clk_ctrl);
+}
+
+static void exynos_ufs_calc_pwm_clk_div(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
+	const unsigned int div = 30, mult = 20;
+	const unsigned long pwm_min = 3 * 1000 * 1000;
+	const unsigned long pwm_max = 9 * 1000 * 1000;
+	const int divs[] = {32, 16, 8, 4};
+	unsigned long clk = 0, _clk, clk_period;
+	int i = 0, clk_idx = -1;
+
+	clk_period = UNIPRO_PCLK_PERIOD(ufs);
+	for (i = 0; i < ARRAY_SIZE(divs); i++) {
+		_clk = NSEC_PER_SEC * mult / (clk_period * divs[i] * div);
+		if (_clk >= pwm_min && _clk <= pwm_max) {
+			if (_clk > clk) {
+				clk_idx = i;
+				clk = _clk;
+			}
+		}
+	}
+
+	if (clk_idx == -1) {
+		ufshcd_dme_get(hba, UIC_ARG_MIB(CMN_PWM_CLK_CTRL), &clk_idx);
+		dev_err(hba->dev,
+			"failed to decide pwm clock divider, will not change\n");
+	}
+
+	attr->cmn_pwm_clk_ctrl = clk_idx & PWM_CLK_CTRL_MASK;
+}
+
+long exynos_ufs_calc_time_cntr(struct exynos_ufs *ufs, long period)
+{
+	const int precise = 10;
+	long pclk_rate = ufs->pclk_rate;
+	long clk_period, fraction;
+
+	clk_period = UNIPRO_PCLK_PERIOD(ufs);
+	fraction = ((NSEC_PER_SEC % pclk_rate) * precise) / pclk_rate;
+
+	return (period * precise) / ((clk_period * precise) + fraction);
+}
+
+static void exynos_ufs_specify_phy_time_attr(struct exynos_ufs *ufs)
+{
+	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
+	struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg;
+
+	t_cfg->tx_linereset_p =
+		exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_p_nsec);
+	t_cfg->tx_linereset_n =
+		exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_n_nsec);
+	t_cfg->tx_high_z_cnt =
+		exynos_ufs_calc_time_cntr(ufs, attr->tx_high_z_cnt_nsec);
+	t_cfg->tx_base_n_val =
+		exynos_ufs_calc_time_cntr(ufs, attr->tx_base_unit_nsec);
+	t_cfg->tx_gran_n_val =
+		exynos_ufs_calc_time_cntr(ufs, attr->tx_gran_unit_nsec);
+	t_cfg->tx_sleep_cnt =
+		exynos_ufs_calc_time_cntr(ufs, attr->tx_sleep_cnt);
+
+	t_cfg->rx_linereset =
+		exynos_ufs_calc_time_cntr(ufs, attr->rx_dif_p_nsec);
+	t_cfg->rx_hibern8_wait =
+		exynos_ufs_calc_time_cntr(ufs, attr->rx_hibern8_wait_nsec);
+	t_cfg->rx_base_n_val =
+		exynos_ufs_calc_time_cntr(ufs, attr->rx_base_unit_nsec);
+	t_cfg->rx_gran_n_val =
+		exynos_ufs_calc_time_cntr(ufs, attr->rx_gran_unit_nsec);
+	t_cfg->rx_sleep_cnt =
+		exynos_ufs_calc_time_cntr(ufs, attr->rx_sleep_cnt);
+	t_cfg->rx_stall_cnt =
+		exynos_ufs_calc_time_cntr(ufs, attr->rx_stall_cnt);
+}
+
+static void exynos_ufs_config_phy_time_attr(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg;
+	int i;
+
+	exynos_ufs_set_pwm_clk_div(ufs);
+
+	exynos_ufs_enable_ov_tm(hba);
+
+	for_each_ufs_rx_lane(ufs, i) {
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_FILLER_ENABLE, i),
+				ufs->drv_data->uic_attr->rx_filler_enable);
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_LINERESET_VAL, i),
+				RX_LINERESET(t_cfg->rx_linereset));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_BASE_NVAL_07_00, i),
+				RX_BASE_NVAL_L(t_cfg->rx_base_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_BASE_NVAL_15_08, i),
+				RX_BASE_NVAL_H(t_cfg->rx_base_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_GRAN_NVAL_07_00, i),
+				RX_GRAN_NVAL_L(t_cfg->rx_gran_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_GRAN_NVAL_10_08, i),
+				RX_GRAN_NVAL_H(t_cfg->rx_gran_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_OV_SLEEP_CNT_TIMER, i),
+				RX_OV_SLEEP_CNT(t_cfg->rx_sleep_cnt));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_OV_STALL_CNT_TIMER, i),
+				RX_OV_STALL_CNT(t_cfg->rx_stall_cnt));
+	}
+
+	for_each_ufs_tx_lane(ufs, i) {
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_LINERESET_P_VAL, i),
+				TX_LINERESET_P(t_cfg->tx_linereset_p));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HIGH_Z_CNT_07_00, i),
+				TX_HIGH_Z_CNT_L(t_cfg->tx_high_z_cnt));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HIGH_Z_CNT_11_08, i),
+				TX_HIGH_Z_CNT_H(t_cfg->tx_high_z_cnt));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_BASE_NVAL_07_00, i),
+				TX_BASE_NVAL_L(t_cfg->tx_base_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_BASE_NVAL_15_08, i),
+				TX_BASE_NVAL_H(t_cfg->tx_base_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_GRAN_NVAL_07_00, i),
+				TX_GRAN_NVAL_L(t_cfg->tx_gran_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_GRAN_NVAL_10_08, i),
+				TX_GRAN_NVAL_H(t_cfg->tx_gran_n_val));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_OV_SLEEP_CNT_TIMER, i),
+				TX_OV_H8_ENTER_EN |
+				TX_OV_SLEEP_CNT(t_cfg->tx_sleep_cnt));
+		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_MIN_ACTIVATETIME, i),
+				ufs->drv_data->uic_attr->tx_min_activatetime);
+	}
+
+	exynos_ufs_disable_ov_tm(hba);
+}
+
+static void exynos_ufs_config_phy_cap_attr(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
+	int i;
+
+	exynos_ufs_enable_ov_tm(hba);
+
+	for_each_ufs_rx_lane(ufs, i) {
+		ufshcd_dme_set(hba,
+				UIC_ARG_MIB_SEL(RX_HS_G1_SYNC_LENGTH_CAP, i),
+				attr->rx_hs_g1_sync_len_cap);
+		ufshcd_dme_set(hba,
+				UIC_ARG_MIB_SEL(RX_HS_G2_SYNC_LENGTH_CAP, i),
+				attr->rx_hs_g2_sync_len_cap);
+		ufshcd_dme_set(hba,
+				UIC_ARG_MIB_SEL(RX_HS_G3_SYNC_LENGTH_CAP, i),
+				attr->rx_hs_g3_sync_len_cap);
+		ufshcd_dme_set(hba,
+				UIC_ARG_MIB_SEL(RX_HS_G1_PREP_LENGTH_CAP, i),
+				attr->rx_hs_g1_prep_sync_len_cap);
+		ufshcd_dme_set(hba,
+				UIC_ARG_MIB_SEL(RX_HS_G2_PREP_LENGTH_CAP, i),
+				attr->rx_hs_g2_prep_sync_len_cap);
+		ufshcd_dme_set(hba,
+				UIC_ARG_MIB_SEL(RX_HS_G3_PREP_LENGTH_CAP, i),
+				attr->rx_hs_g3_prep_sync_len_cap);
+	}
+
+	if (attr->rx_adv_fine_gran_sup_en == 0) {
+		for_each_ufs_rx_lane(ufs, i) {
+			ufshcd_dme_set(hba,
+				UIC_ARG_MIB_SEL(RX_ADV_GRANULARITY_CAP, i), 0);
+
+			if (attr->rx_min_actv_time_cap)
+				ufshcd_dme_set(hba,
+					UIC_ARG_MIB_SEL(RX_MIN_ACTIVATETIME_CAP,
+						i), attr->rx_min_actv_time_cap);
+
+			if (attr->rx_hibern8_time_cap)
+				ufshcd_dme_set(hba,
+					UIC_ARG_MIB_SEL(RX_HIBERN8TIME_CAP, i),
+						attr->rx_hibern8_time_cap);
+		}
+	} else if (attr->rx_adv_fine_gran_sup_en == 1) {
+		for_each_ufs_rx_lane(ufs, i) {
+			if (attr->rx_adv_fine_gran_step)
+				ufshcd_dme_set(hba,
+					UIC_ARG_MIB_SEL(RX_ADV_GRANULARITY_CAP,
+						i), RX_ADV_FINE_GRAN_STEP(
+						attr->rx_adv_fine_gran_step));
+
+			if (attr->rx_adv_min_actv_time_cap)
+				ufshcd_dme_set(hba,
+					UIC_ARG_MIB_SEL(
+						RX_ADV_MIN_ACTIVATETIME_CAP, i),
+						attr->rx_adv_min_actv_time_cap);
+
+			if (attr->rx_adv_hibern8_time_cap)
+				ufshcd_dme_set(hba,
+					UIC_ARG_MIB_SEL(RX_ADV_HIBERN8TIME_CAP,
+						i),
+						attr->rx_adv_hibern8_time_cap);
+		}
+	}
+
+	exynos_ufs_disable_ov_tm(hba);
+}
+
+static void exynos_ufs_establish_connt(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	enum {
+		DEV_ID		= 0x00,
+		PEER_DEV_ID	= 0x01,
+		PEER_CPORT_ID	= 0x00,
+		TRAFFIC_CLASS	= 0x00,
+	};
+
+	/* allow cport attributes to be set */
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_IDLE);
+
+	/* local unipro attributes */
+	ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID), DEV_ID);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID_VALID), TRUE);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID), PEER_DEV_ID);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID), PEER_CPORT_ID);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS), CPORT_DEF_FLAGS);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS), TRAFFIC_CLASS);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_CONNECTED);
+}
+
+static void exynos_ufs_config_smu(struct exynos_ufs *ufs)
+{
+	u32 reg, val;
+
+	exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val);
+
+	/* make encryption disabled by default */
+	reg = ufsp_readl(ufs, UFSPRSECURITY);
+	ufsp_writel(ufs, reg | NSSMU, UFSPRSECURITY);
+	ufsp_writel(ufs, 0x0, UFSPSBEGIN0);
+	ufsp_writel(ufs, 0xffffffff, UFSPSEND0);
+	ufsp_writel(ufs, 0xff, UFSPSLUN0);
+	ufsp_writel(ufs, 0xf1, UFSPSCTRL0);
+
+	exynos_ufs_auto_ctrl_hcc_restore(ufs, &val);
+}
+
+static void exynos_ufs_config_sync_pattern_mask(struct exynos_ufs *ufs,
+					struct uic_pwr_mode *pwr)
+{
+	struct ufs_hba *hba = ufs->hba;
+	u8 g = pwr->gear;
+	u32 mask, sync_len;
+	enum {
+		SYNC_LEN_G1 = 80 * 1000, /* 80us */
+		SYNC_LEN_G2 = 40 * 1000, /* 44us */
+		SYNC_LEN_G3 = 20 * 1000, /* 20us */
+	};
+	int i;
+
+	if (g == 1)
+		sync_len = SYNC_LEN_G1;
+	else if (g == 2)
+		sync_len = SYNC_LEN_G2;
+	else if (g == 3)
+		sync_len = SYNC_LEN_G3;
+	else
+		return;
+
+	mask = exynos_ufs_calc_time_cntr(ufs, sync_len);
+	mask = (mask >> 8) & 0xff;
+
+	exynos_ufs_enable_ov_tm(hba);
+
+	for_each_ufs_rx_lane(ufs, i)
+		ufshcd_dme_set(hba,
+			UIC_ARG_MIB_SEL(RX_SYNC_MASK_LENGTH, i), mask);
+
+	exynos_ufs_disable_ov_tm(hba);
+}
+
+static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
+				struct ufs_pa_layer_attr *pwr_max,
+				struct ufs_pa_layer_attr *final)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	struct phy *generic_phy = ufs->phy;
+	struct uic_pwr_mode *pwr_req = &ufs->pwr_req;
+	struct uic_pwr_mode *pwr_act = &ufs->pwr_act;
+
+	final->gear_rx
+		= pwr_act->gear = min_t(u32, pwr_max->gear_rx, pwr_req->gear);
+	final->gear_tx
+		= pwr_act->gear = min_t(u32, pwr_max->gear_tx, pwr_req->gear);
+	final->lane_rx
+		= pwr_act->lane = min_t(u32, pwr_max->lane_rx, pwr_req->lane);
+	final->lane_tx
+		= pwr_act->lane = min_t(u32, pwr_max->lane_tx, pwr_req->lane);
+	final->pwr_rx = pwr_act->mode = pwr_req->mode;
+	final->pwr_tx = pwr_act->mode = pwr_req->mode;
+	final->hs_rate = pwr_act->hs_series = pwr_req->hs_series;
+
+	/* save and configure l2 timer */
+	pwr_act->l_l2_timer[0] = pwr_req->l_l2_timer[0];
+	pwr_act->l_l2_timer[1] = pwr_req->l_l2_timer[1];
+	pwr_act->l_l2_timer[2] = pwr_req->l_l2_timer[2];
+	pwr_act->r_l2_timer[0] = pwr_req->r_l2_timer[0];
+	pwr_act->r_l2_timer[1] = pwr_req->r_l2_timer[1];
+	pwr_act->r_l2_timer[2] = pwr_req->r_l2_timer[2];
+
+	ufshcd_dme_set(hba,
+		UIC_ARG_MIB(DL_FC0PROTTIMEOUTVAL), pwr_act->l_l2_timer[0]);
+	ufshcd_dme_set(hba,
+		UIC_ARG_MIB(DL_TC0REPLAYTIMEOUTVAL), pwr_act->l_l2_timer[1]);
+	ufshcd_dme_set(hba,
+		UIC_ARG_MIB(DL_AFC0REQTIMEOUTVAL), pwr_act->l_l2_timer[2]);
+	ufshcd_dme_set(hba,
+		UIC_ARG_MIB(PA_PWRMODEUSERDATA0), pwr_act->r_l2_timer[0]);
+	ufshcd_dme_set(hba,
+		UIC_ARG_MIB(PA_PWRMODEUSERDATA1), pwr_act->r_l2_timer[1]);
+	ufshcd_dme_set(hba,
+		UIC_ARG_MIB(PA_PWRMODEUSERDATA2), pwr_act->r_l2_timer[2]);
+
+	unipro_writel(ufs,
+		pwr_act->l_l2_timer[0], UNIPRO_DME_PWR_REQ_LOCALL2TIMER0);
+	unipro_writel(ufs,
+		pwr_act->l_l2_timer[1], UNIPRO_DME_PWR_REQ_LOCALL2TIMER1);
+	unipro_writel(ufs,
+		pwr_act->l_l2_timer[2], UNIPRO_DME_PWR_REQ_LOCALL2TIMER2);
+	unipro_writel(ufs,
+		pwr_act->r_l2_timer[0], UNIPRO_DME_PWR_REQ_REMOTEL2TIMER0);
+	unipro_writel(ufs,
+		pwr_act->r_l2_timer[1], UNIPRO_DME_PWR_REQ_REMOTEL2TIMER1);
+	unipro_writel(ufs,
+		pwr_act->r_l2_timer[2], UNIPRO_DME_PWR_REQ_REMOTEL2TIMER2);
+
+	if (ufs->drv_data->pre_pwr_change)
+		ufs->drv_data->pre_pwr_change(ufs, pwr_act);
+
+	if (IS_UFS_PWR_MODE_HS(pwr_act->mode)) {
+		exynos_ufs_config_sync_pattern_mask(ufs, pwr_act);
+
+		switch (pwr_act->hs_series) {
+		case PA_HS_MODE_A:
+		case PA_HS_MODE_B:
+			phy_calibrate(generic_phy);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+#define PWR_MODE_STR_LEN	64
+static int exynos_ufs_post_pwr_mode(struct ufs_hba *hba,
+				struct ufs_pa_layer_attr *pwr_max,
+				struct ufs_pa_layer_attr *pwr_req)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	struct phy *generic_phy = ufs->phy;
+	struct uic_pwr_mode *pwr = &ufs->pwr_act;
+	char pwr_str[PWR_MODE_STR_LEN] = "";
+	int ret = 0;
+
+	if (ufs->drv_data->post_pwr_change)
+		ufs->drv_data->post_pwr_change(ufs, pwr);
+
+	if (IS_UFS_PWR_MODE_HS(pwr->mode)) {
+		switch (pwr->hs_series) {
+		case PA_HS_MODE_A:
+		case PA_HS_MODE_B:
+			phy_calibrate(generic_phy);
+			break;
+		}
+
+		snprintf(pwr_str, sizeof(pwr_str), "Fast%s series_%s G_%d L_%d",
+			pwr->mode == FASTAUTO_MODE ? "_Auto" : "",
+			pwr->hs_series == PA_HS_MODE_A ? "A" : "B",
+			pwr->gear, pwr->lane);
+	} else if (IS_UFS_PWR_MODE_PWM(pwr->mode)) {
+		snprintf(pwr_str, sizeof(pwr_str), "Slow%s G_%d L_%d",
+			pwr->mode == SLOWAUTO_MODE ? "_Auto" : "",
+			pwr->gear, pwr->lane);
+	}
+
+	dev_info(hba->dev, "Power mode change %d : %s\n", ret, pwr_str);
+	return ret;
+}
+
+static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba,
+						int tag, bool op)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	u32 type;
+
+	type =  hci_readl(ufs, HCI_UTRL_NEXUS_TYPE);
+
+	if (op)
+		hci_writel(ufs, type | (1 << tag), HCI_UTRL_NEXUS_TYPE);
+	else
+		hci_writel(ufs, type & ~(1 << tag), HCI_UTRL_NEXUS_TYPE);
+}
+
+static void exynos_ufs_specify_nexus_t_tm_req(struct ufs_hba *hba,
+						int tag, u8 func)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	u32 type;
+
+	type =  hci_readl(ufs, HCI_UTMRL_NEXUS_TYPE);
+
+	switch (func) {
+	case UFS_ABORT_TASK:
+	case UFS_QUERY_TASK:
+		hci_writel(ufs, type | (1 << tag), HCI_UTMRL_NEXUS_TYPE);
+		break;
+	case UFS_ABORT_TASK_SET:
+	case UFS_CLEAR_TASK_SET:
+	case UFS_LOGICAL_RESET:
+	case UFS_QUERY_TASK_SET:
+		hci_writel(ufs, type & ~(1 << tag), HCI_UTMRL_NEXUS_TYPE);
+		break;
+	}
+}
+
+static void exynos_ufs_phy_init(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+	struct phy *generic_phy = ufs->phy;
+
+	if (ufs->avail_ln_rx == 0 || ufs->avail_ln_tx == 0) {
+		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILRXDATALANES),
+			&ufs->avail_ln_rx);
+		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILTXDATALANES),
+			&ufs->avail_ln_tx);
+		WARN(ufs->avail_ln_rx != ufs->avail_ln_tx,
+			"available data lane is not equal(rx:%d, tx:%d)\n",
+			ufs->avail_ln_rx, ufs->avail_ln_tx);
+	}
+
+	phy_set_bus_width(generic_phy, ufs->avail_ln_rx);
+	phy_init(generic_phy);
+}
+
+static void exynos_ufs_config_unipro(struct exynos_ufs *ufs)
+{
+	struct ufs_hba *hba = ufs->hba;
+
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_CLK_PERIOD),
+		DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTRAILINGCLOCKS),
+			ufs->drv_data->uic_attr->tx_trailingclks);
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE),
+			ufs->drv_data->uic_attr->pa_dbg_option_suite);
+}
+
+static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index)
+{
+	switch (index) {
+	case UNIPRO_L1_5:
+		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_PA_LAYER);
+		break;
+	case UNIPRO_L2:
+		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DL_LAYER);
+		break;
+	case UNIPRO_L3:
+		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_N_LAYER);
+		break;
+	case UNIPRO_L4:
+		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_T_LAYER);
+		break;
+	case UNIPRO_DME:
+		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DME_LAYER);
+		break;
+	}
+}
+
+static int exynos_ufs_pre_link(struct ufs_hba *hba)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+	/* hci */
+	exynos_ufs_config_intr(ufs, DFES_DEF_L2_ERRS, UNIPRO_L2);
+	exynos_ufs_config_intr(ufs, DFES_DEF_L3_ERRS, UNIPRO_L3);
+	exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4);
+	exynos_ufs_set_unipro_pclk_div(ufs);
+
+	/* unipro */
+	exynos_ufs_config_unipro(ufs);
+
+	/* m-phy */
+	exynos_ufs_phy_init(ufs);
+	exynos_ufs_config_phy_time_attr(ufs);
+	exynos_ufs_config_phy_cap_attr(ufs);
+
+	if (ufs->drv_data->pre_link)
+		ufs->drv_data->pre_link(ufs);
+
+	return 0;
+}
+
+static void exynos_ufs_fit_aggr_timeout(struct exynos_ufs *ufs)
+{
+	u32 val;
+
+	val = exynos_ufs_calc_time_cntr(ufs, IATOVAL_NSEC / CNTR_DIV_VAL);
+	hci_writel(ufs, val & CNT_VAL_1US_MASK, HCI_1US_TO_CNT_VAL);
+}
+
+static int exynos_ufs_post_link(struct ufs_hba *hba)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	struct phy *generic_phy = ufs->phy;
+	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
+
+	exynos_ufs_establish_connt(ufs);
+	exynos_ufs_fit_aggr_timeout(ufs);
+
+	hci_writel(ufs, 0xa, HCI_DATA_REORDER);
+	hci_writel(ufs, PRDT_PREFECT_EN | PRDT_SET_SIZE(12),
+			HCI_TXPRDT_ENTRY_SIZE);
+	hci_writel(ufs, PRDT_SET_SIZE(12), HCI_RXPRDT_ENTRY_SIZE);
+	hci_writel(ufs, (1 << hba->nutrs) - 1, HCI_UTRL_NEXUS_TYPE);
+	hci_writel(ufs, (1 << hba->nutmrs) - 1, HCI_UTMRL_NEXUS_TYPE);
+	hci_writel(ufs, 0xf, HCI_AXIDMA_RWDATA_BURST_LEN);
+
+	if (ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB)
+		ufshcd_dme_set(hba,
+			UIC_ARG_MIB(T_DBG_SKIP_INIT_HIBERN8_EXIT), TRUE);
+
+	if (attr->pa_granularity) {
+		exynos_ufs_enable_dbg_mode(hba);
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_GRANULARITY),
+				attr->pa_granularity);
+		exynos_ufs_disable_dbg_mode(hba);
+
+		if (attr->pa_tactivate)
+			ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE),
+					attr->pa_tactivate);
+		if (attr->pa_hibern8time &&
+		    !(ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER))
+			ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
+					attr->pa_hibern8time);
+	}
+
+	if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) {
+		if (!attr->pa_granularity)
+			ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY),
+					&attr->pa_granularity);
+		if (!attr->pa_hibern8time)
+			ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
+					&attr->pa_hibern8time);
+		/*
+		 * not wait for HIBERN8 time to exit hibernation
+		 */
+		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), 0);
+
+		if (attr->pa_granularity < 1 || attr->pa_granularity > 6) {
+			/* Valid range for granularity: 1 ~ 6 */
+			dev_warn(hba->dev,
+				"%s: pa_granularty %d is invalid, assuming backwards compatibility\n",
+				__func__,
+				attr->pa_granularity);
+			attr->pa_granularity = 6;
+		}
+	}
+
+	phy_calibrate(generic_phy);
+
+	if (ufs->drv_data->post_link)
+		ufs->drv_data->post_link(ufs);
+
+	return 0;
+}
+
+static void exynos_ufs_specify_pwr_mode(struct device_node *np,
+				struct exynos_ufs *ufs)
+{
+	struct uic_pwr_mode *pwr = &ufs->pwr_req;
+	const char *str = NULL;
+
+	if (!of_property_read_string(np, "ufs,pwr-attr-mode", &str)) {
+		if (!strncmp(str, "FAST", sizeof("FAST")))
+			pwr->mode = FAST_MODE;
+		else if (!strncmp(str, "SLOW", sizeof("SLOW")))
+			pwr->mode = SLOW_MODE;
+		else if (!strncmp(str, "FAST_auto", sizeof("FAST_auto")))
+			pwr->mode = FASTAUTO_MODE;
+		else if (!strncmp(str, "SLOW_auto", sizeof("SLOW_auto")))
+			pwr->mode = SLOWAUTO_MODE;
+		else
+			pwr->mode = FAST_MODE;
+	} else {
+		pwr->mode = FAST_MODE;
+	}
+
+	if (of_property_read_u32(np, "ufs,pwr-attr-lane", &pwr->lane))
+		pwr->lane = 1;
+
+	if (of_property_read_u32(np, "ufs,pwr-attr-gear", &pwr->gear))
+		pwr->gear = 1;
+
+	if (IS_UFS_PWR_MODE_HS(pwr->mode)) {
+		if (!of_property_read_string(np,
+					"ufs,pwr-attr-hs-series", &str)) {
+			if (!strncmp(str, "HS_rate_a", sizeof("HS_rate_a")))
+				pwr->hs_series = PA_HS_MODE_A;
+			else if (!strncmp(str, "HS_rate_b",
+				    sizeof("HS_rate_b")))
+				pwr->hs_series = PA_HS_MODE_B;
+			else
+				pwr->hs_series = PA_HS_MODE_A;
+		} else {
+			pwr->hs_series = PA_HS_MODE_A;
+		}
+	}
+
+	if (of_property_read_u32_array(
+		np, "ufs,pwr-local-l2-timer", pwr->l_l2_timer, 3)) {
+		pwr->l_l2_timer[0] = FC0PROTTIMEOUTVAL;
+		pwr->l_l2_timer[1] = TC0REPLAYTIMEOUTVAL;
+		pwr->l_l2_timer[2] = AFC0REQTIMEOUTVAL;
+	}
+
+	if (of_property_read_u32_array(
+		np, "ufs,pwr-remote-l2-timer", pwr->r_l2_timer, 3)) {
+		pwr->r_l2_timer[0] = FC0PROTTIMEOUTVAL;
+		pwr->r_l2_timer[1] = TC0REPLAYTIMEOUTVAL;
+		pwr->r_l2_timer[2] = AFC0REQTIMEOUTVAL;
+	}
+}
+
+static int exynos_ufs_parse_dt(struct device *dev, struct exynos_ufs *ufs)
+{
+	struct device_node *np = dev->of_node;
+	struct exynos_ufs_drv_data *drv_data = &exynos_ufs_drvs;
+	struct exynos_ufs_uic_attr *attr;
+	u32 freq[2];
+	int ret;
+
+	while (drv_data->compatible) {
+		if (of_device_is_compatible(np, drv_data->compatible)) {
+			ufs->drv_data = drv_data;
+			break;
+		}
+		drv_data++;
+	}
+
+	if (ufs->drv_data && ufs->drv_data->uic_attr) {
+		attr = ufs->drv_data->uic_attr;
+	} else {
+		dev_err(dev, "failed to get uic attributes\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = of_property_read_u32_array(np,
+			"pclk-freq-avail-range", freq, ARRAY_SIZE(freq));
+	if (!ret) {
+		ufs->pclk_avail_min = freq[0];
+		ufs->pclk_avail_max = freq[1];
+	} else {
+		dev_err(dev, "failed to get available pclk range\n");
+		goto out;
+	}
+
+	exynos_ufs_specify_pwr_mode(np, ufs);
+
+	if (!of_property_read_u32(np, "ufs-rx-adv-fine-gran-sup_en",
+				&attr->rx_adv_fine_gran_sup_en)) {
+		if (attr->rx_adv_fine_gran_sup_en == 0) {
+			/* 100us step */
+			if (of_property_read_u32(np,
+					"ufs-rx-min-activate-time-cap",
+					&attr->rx_min_actv_time_cap))
+				dev_warn(dev,
+					"ufs-rx-min-activate-time-cap is empty\n");
+
+			if (of_property_read_u32(np,
+					"ufs-rx-hibern8-time-cap",
+					&attr->rx_hibern8_time_cap))
+				dev_warn(dev,
+					"ufs-rx-hibern8-time-cap is empty\n");
+		} else if (attr->rx_adv_fine_gran_sup_en == 1) {
+			/* fine granularity step */
+			if (of_property_read_u32(np,
+					"ufs-rx-adv-fine-gran-step",
+					&attr->rx_adv_fine_gran_step))
+				dev_warn(dev,
+					"ufs-rx-adv-fine-gran-step is empty\n");
+
+			if (of_property_read_u32(np,
+					"ufs-rx-adv-min-activate-time-cap",
+					&attr->rx_adv_min_actv_time_cap))
+				dev_warn(dev,
+					"ufs-rx-adv-min-activate-time-cap is empty\n");
+
+			if (of_property_read_u32(np,
+					"ufs-rx-adv-hibern8-time-cap",
+					&attr->rx_adv_hibern8_time_cap))
+				dev_warn(dev,
+					"ufs-rx-adv-hibern8-time-cap is empty\n");
+		} else {
+			dev_warn(dev,
+				"not supported val for ufs-rx-adv-fine-gran-sup_en %d\n",
+				attr->rx_adv_fine_gran_sup_en);
+		}
+	} else {
+		attr->rx_adv_fine_gran_sup_en = 0xf;
+	}
+
+	if (!of_property_read_u32(np,
+				"ufs-pa-granularity", &attr->pa_granularity)) {
+		if (of_property_read_u32(np,
+				"ufs-pa-tacctivate", &attr->pa_tactivate))
+			dev_warn(dev, "ufs-pa-tacctivate is empty\n");
+
+		if (of_property_read_u32(np,
+				"ufs-pa-hibern8time", &attr->pa_hibern8time))
+			dev_warn(dev, "ufs-pa-hibern8time is empty\n");
+	}
+
+out:
+	return ret;
+}
+
+static int exynos_ufs_init(struct ufs_hba *hba)
+{
+	struct device *dev = hba->dev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct exynos_ufs *ufs;
+	struct resource *res;
+	int ret;
+
+	ufs = devm_kzalloc(dev, sizeof(*ufs), GFP_KERNEL);
+	if (!ufs)
+		return -ENOMEM;
+
+	/* exynos-specific hci */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vs_hci");
+	ufs->reg_hci = devm_ioremap_resource(dev, res);
+	if (!ufs->reg_hci) {
+		dev_err(dev, "cannot ioremap for hci vendor register\n");
+		return -ENOMEM;
+	}
+
+	/* unipro */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "unipro");
+	ufs->reg_unipro = devm_ioremap_resource(dev, res);
+	if (!ufs->reg_unipro) {
+		dev_err(dev, "cannot ioremap for unipro register\n");
+		return -ENOMEM;
+	}
+
+	/* ufs protector */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ufsp");
+	ufs->reg_ufsp = devm_ioremap_resource(dev, res);
+	if (!ufs->reg_ufsp) {
+		dev_err(dev, "cannot ioremap for ufs protector register\n");
+		return -ENOMEM;
+	}
+
+	ret = exynos_ufs_parse_dt(dev, ufs);
+	if (ret) {
+		dev_err(dev, "failed to get dt info.\n");
+		goto out;
+	}
+
+	ufs->phy = devm_phy_get(dev, "ufs-phy");
+	if (IS_ERR(ufs->phy)) {
+		ret = PTR_ERR(ufs->phy);
+		dev_err(dev, "failed to get ufs-phy\n");
+		goto out;
+	}
+
+	ret = phy_power_on(ufs->phy);
+	if (ret)
+		goto phy_exit;
+
+	ufs->hba = hba;
+	ufs->opts = ufs->drv_data->opts |
+		EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB |
+		EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER;
+	ufs->rx_sel_idx = PA_MAXDATALANES;
+	if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX)
+		ufs->rx_sel_idx = 0;
+	hba->priv = (void *)ufs;
+	hba->quirks = ufs->drv_data->quirks;
+	if (ufs->drv_data->drv_init) {
+		ret = ufs->drv_data->drv_init(dev, ufs);
+		if (ret) {
+			dev_err(dev, "failed to init drv-data\n");
+			goto phy_off;
+		}
+	}
+
+	ret = exynos_ufs_get_clk_info(ufs);
+	if (ret)
+		goto phy_off;
+	exynos_ufs_specify_phy_time_attr(ufs);
+	exynos_ufs_config_smu(ufs);
+	return 0;
+
+phy_off:
+	phy_power_off(ufs->phy);
+phy_exit:
+	phy_exit(ufs->phy);
+	hba->priv = NULL;
+out:
+	return ret;
+}
+
+static int exynos_ufs_host_reset(struct ufs_hba *hba)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	unsigned long timeout = jiffies + msecs_to_jiffies(1);
+	u32 val;
+	int ret = 0;
+
+	exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val);
+
+	hci_writel(ufs, UFS_SW_RST_MASK, HCI_SW_RST);
+
+	do {
+		if (!(hci_readl(ufs, HCI_SW_RST) & UFS_SW_RST_MASK))
+			goto out;
+	} while (time_before(jiffies, timeout));
+
+	dev_err(hba->dev, "timeout host sw-reset\n");
+	ret = -ETIMEDOUT;
+
+out:
+	exynos_ufs_auto_ctrl_hcc_restore(ufs, &val);
+	return ret;
+}
+
+static void exynos_ufs_dev_hw_reset(struct ufs_hba *hba)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+	hci_writel(ufs, 0 << 0, HCI_GPIO_OUT);
+	udelay(5);
+	hci_writel(ufs, 1 << 0, HCI_GPIO_OUT);
+}
+
+static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
+
+	if (!enter) {
+		if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
+			exynos_ufs_disable_auto_ctrl_hcc(ufs);
+		exynos_ufs_ungate_clks(ufs);
+
+		if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) {
+			const unsigned int granularity_tbl[] = {
+				1, 4, 8, 16, 32, 100
+			};
+			int h8_time = attr->pa_hibern8time *
+				granularity_tbl[attr->pa_granularity - 1];
+			unsigned long us;
+			s64 delta;
+
+			do {
+				delta = h8_time - ktime_us_delta(ktime_get(),
+							ufs->entry_hibern8_t);
+				if (delta <= 0)
+					break;
+
+				us = min_t(s64, delta, USEC_PER_MSEC);
+				if (us >= 10)
+					usleep_range(us, us + 10);
+			} while (1);
+		}
+	}
+}
+
+static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+	if (!enter) {
+		struct uic_pwr_mode *pwr = &ufs->pwr_act;
+		u32 mode = 0;
+
+		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_PWRMODE), &mode);
+		if (mode != (pwr->mode << 4 | pwr->mode)) {
+			dev_warn(hba->dev, "%s: power mode change\n", __func__);
+			hba->pwr_info.pwr_rx = (mode >> 4) & 0xf;
+			hba->pwr_info.pwr_tx = mode & 0xf;
+			ufshcd_config_pwr_mode(hba, &hba->max_pwr_info.info);
+		}
+
+		if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB))
+			exynos_ufs_establish_connt(ufs);
+	} else {
+		ufs->entry_hibern8_t = ktime_get();
+		exynos_ufs_gate_clks(ufs);
+		if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
+			exynos_ufs_enable_auto_ctrl_hcc(ufs);
+	}
+}
+
+static int exynos_ufs_hce_enable_notify(struct ufs_hba *hba,
+					enum ufs_notify_change_status status)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+	int ret = 0;
+
+	switch (status) {
+	case PRE_CHANGE:
+		ret = exynos_ufs_host_reset(hba);
+		if (ret)
+			return ret;
+		exynos_ufs_dev_hw_reset(hba);
+		break;
+	case POST_CHANGE:
+		exynos_ufs_calc_pwm_clk_div(ufs);
+		if (!(ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL))
+			exynos_ufs_enable_auto_ctrl_hcc(ufs);
+		break;
+	}
+
+	return ret;
+}
+
+static int exynos_ufs_link_startup_notify(struct ufs_hba *hba,
+					  enum ufs_notify_change_status status)
+{
+	int ret = 0;
+
+	switch (status) {
+	case PRE_CHANGE:
+		ret = exynos_ufs_pre_link(hba);
+		break;
+	case POST_CHANGE:
+		ret = exynos_ufs_post_link(hba);
+		break;
+	}
+
+	return ret;
+}
+
+static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba,
+					enum ufs_notify_change_status status,
+					struct ufs_pa_layer_attr *pwr_max,
+					struct ufs_pa_layer_attr *pwr_req)
+{
+	int ret = 0;
+
+	switch (status) {
+	case PRE_CHANGE:
+		ret = exynos_ufs_pre_pwr_mode(hba, pwr_max, pwr_req);
+		break;
+	case POST_CHANGE:
+		ret = exynos_ufs_post_pwr_mode(hba, NULL, pwr_req);
+		break;
+	}
+
+	return ret;
+}
+
+static void exynos_ufs_hibern8_notify(struct ufs_hba *hba,
+				     enum uic_cmd_dme enter,
+				     enum ufs_notify_change_status notify)
+{
+	switch ((u8)notify) {
+	case PRE_CHANGE:
+		exynos_ufs_pre_hibern8(hba, enter);
+		break;
+	case POST_CHANGE:
+		exynos_ufs_post_hibern8(hba, enter);
+		break;
+	}
+}
+
+static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+	if (!ufshcd_is_link_active(hba))
+		phy_power_off(ufs->phy);
+
+	return 0;
+}
+
+static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
+{
+	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
+
+	if (!ufshcd_is_link_active(hba))
+		phy_power_on(ufs->phy);
+
+	exynos_ufs_config_smu(ufs);
+
+	return 0;
+}
+
+static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
+	.name				= "exynos_ufs",
+	.init				= exynos_ufs_init,
+	.hce_enable_notify		= exynos_ufs_hce_enable_notify,
+	.link_startup_notify		= exynos_ufs_link_startup_notify,
+	.pwr_change_notify		= exynos_ufs_pwr_change_notify,
+	.setup_xfer_req			= exynos_ufs_specify_nexus_t_xfer_req,
+	.setup_task_mgmt		= exynos_ufs_specify_nexus_t_tm_req,
+	.hibern8_notify			= exynos_ufs_hibern8_notify,
+	.suspend			= exynos_ufs_suspend,
+	.resume				= exynos_ufs_resume,
+};
+
+static int exynos_ufs_probe(struct platform_device *pdev)
+{
+	int err;
+	struct device *dev = &pdev->dev;
+
+	err = ufshcd_pltfrm_init(pdev, &ufs_hba_exynos_ops);
+	if (err)
+		dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
+
+	return err;
+}
+
+static int exynos_ufs_remove(struct platform_device *pdev)
+{
+	struct ufs_hba *hba =  platform_get_drvdata(pdev);
+
+	pm_runtime_get_sync(&(pdev)->dev);
+	ufshcd_remove(hba);
+	return 0;
+}
+
+struct exynos_ufs_drv_data exynos_ufs_drvs = {
+
+	.compatible		= "samsung,exynos7-ufs",
+	.uic_attr		= &exynos7_uic_attr,
+	.quirks			= UFSHCD_QUIRK_PRDT_BYTE_GRAN |
+				  UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
+				  UFSHCI_QUIRK_BROKEN_HCE |
+				  UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR,
+	.opts			= EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL |
+				  EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
+				  EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
+	.drv_init		= exynos7_ufs_drv_init,
+	.pre_link		= exynos7_ufs_pre_link,
+	.post_link		= exynos7_ufs_post_link,
+	.pre_pwr_change		= exynos7_ufs_pre_pwr_change,
+	.post_pwr_change	= exynos7_ufs_post_pwr_change,
+};
+
+static const struct of_device_id exynos_ufs_of_match[] = {
+	{ .compatible = "samsung,exynos7-ufs",
+	  .data	      = &exynos_ufs_drvs },
+	{},
+};
+
+static const struct dev_pm_ops exynos_ufs_pm_ops = {
+	.suspend	= ufshcd_pltfrm_suspend,
+	.resume		= ufshcd_pltfrm_resume,
+	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
+	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
+	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
+};
+
+static struct platform_driver exynos_ufs_pltform = {
+	.probe	= exynos_ufs_probe,
+	.remove	= exynos_ufs_remove,
+	.shutdown = ufshcd_pltfrm_shutdown,
+	.driver	= {
+		.name	= "exynos-ufshc",
+		.pm	= &exynos_ufs_pm_ops,
+		.of_match_table = of_match_ptr(exynos_ufs_of_match),
+	},
+};
+module_platform_driver(exynos_ufs_pltform);
diff --git a/drivers/scsi/ufs/ufs-exynos.h b/drivers/scsi/ufs/ufs-exynos.h
new file mode 100644
index 000000000000..98efffc2c19a
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-exynos.h
@@ -0,0 +1,268 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * UFS Host Controller driver for Exynos specific extensions
+ *
+ * Copyright (C) 2014-2015 Samsung Electronics Co., Ltd.
+ *
+ */
+
+#ifndef _UFS_EXYNOS_H_
+#define _UFS_EXYNOS_H_
+
+/*
+ * UNIPRO registers
+ */
+#define UNIPRO_DBG_FORCE_DME_CTRL_STATE		0x150
+
+/*
+ * MIBs for PA debug registers
+ */
+#define PA_DBG_CLK_PERIOD	0x9514
+#define PA_DBG_TXPHY_CFGUPDT	0x9518
+#define PA_DBG_RXPHY_CFGUPDT	0x9519
+#define PA_DBG_MODE		0x9529
+#define PA_DBG_SKIP_RESET_PHY	0x9539
+#define PA_DBG_OV_TM		0x9540
+#define PA_DBG_SKIP_LINE_RESET	0x9541
+#define PA_DBG_LINE_RESET_REQ	0x9543
+#define PA_DBG_OPTION_SUITE	0x9564
+#define PA_DBG_OPTION_SUITE_DYN	0x9565
+
+/*
+ * MIBs for Transport Layer debug registers
+ */
+#define T_DBG_SKIP_INIT_HIBERN8_EXIT	0xc001
+
+/*
+ * Exynos MPHY attributes
+ */
+#define TX_LINERESET_N_VAL	0x0277
+#define TX_LINERESET_N(v)	(((v) >> 10) & 0xFF)
+#define TX_LINERESET_P_VAL	0x027D
+#define TX_LINERESET_P(v)	(((v) >> 12) & 0xFF)
+#define TX_OV_SLEEP_CNT_TIMER	0x028E
+#define TX_OV_H8_ENTER_EN	(1 << 7)
+#define TX_OV_SLEEP_CNT(v)	(((v) >> 5) & 0x7F)
+#define TX_HIGH_Z_CNT_11_08	0x028C
+#define TX_HIGH_Z_CNT_H(v)	(((v) >> 8) & 0xF)
+#define TX_HIGH_Z_CNT_07_00	0x028D
+#define TX_HIGH_Z_CNT_L(v)	((v) & 0xFF)
+#define TX_BASE_NVAL_07_00	0x0293
+#define TX_BASE_NVAL_L(v)	((v) & 0xFF)
+#define TX_BASE_NVAL_15_08	0x0294
+#define TX_BASE_NVAL_H(v)	(((v) >> 8) & 0xFF)
+#define TX_GRAN_NVAL_07_00	0x0295
+#define TX_GRAN_NVAL_L(v)	((v) & 0xFF)
+#define TX_GRAN_NVAL_10_08	0x0296
+#define TX_GRAN_NVAL_H(v)	(((v) >> 8) & 0x3)
+
+#define RX_FILLER_ENABLE	0x0316
+#define RX_FILLER_EN		(1 << 1)
+#define RX_LINERESET_VAL	0x0317
+#define RX_LINERESET(v)	(((v) >> 12) & 0xFF)
+#define RX_LCC_IGNORE		0x0318
+#define RX_SYNC_MASK_LENGTH	0x0321
+#define RX_HIBERN8_WAIT_VAL_BIT_20_16	0x0331
+#define RX_HIBERN8_WAIT_VAL_BIT_15_08	0x0332
+#define RX_HIBERN8_WAIT_VAL_BIT_07_00	0x0333
+#define RX_OV_SLEEP_CNT_TIMER	0x0340
+#define RX_OV_SLEEP_CNT(v)	(((v) >> 6) & 0x1F)
+#define RX_OV_STALL_CNT_TIMER	0x0341
+#define RX_OV_STALL_CNT(v)	(((v) >> 4) & 0xFF)
+#define RX_BASE_NVAL_07_00	0x0355
+#define RX_BASE_NVAL_L(v)	((v) & 0xFF)
+#define RX_BASE_NVAL_15_08	0x0354
+#define RX_BASE_NVAL_H(v)	(((v) >> 8) & 0xFF)
+#define RX_GRAN_NVAL_07_00	0x0353
+#define RX_GRAN_NVAL_L(v)	((v) & 0xFF)
+#define RX_GRAN_NVAL_10_08	0x0352
+#define RX_GRAN_NVAL_H(v)	(((v) >> 8) & 0x3)
+
+#define CMN_PWM_CLK_CTRL	0x0402
+#define PWM_CLK_CTRL_MASK	0x3
+
+#define IATOVAL_NSEC		20000	/* unit: ns */
+#define UNIPRO_PCLK_PERIOD(ufs) (NSEC_PER_SEC / ufs->pclk_rate)
+
+struct exynos_ufs;
+
+struct uic_pwr_mode {
+	u32 lane;
+	u32 gear;
+	u8 mode;
+	u8 hs_series;
+	u32 l_l2_timer[3];	/* local */
+	u32 r_l2_timer[3];	/* remote */
+};
+
+struct exynos_ufs_uic_attr {
+	/* TX Attributes */
+	unsigned int tx_trailingclks;
+	unsigned int tx_dif_p_nsec;
+	unsigned int tx_dif_n_nsec;
+	unsigned int tx_high_z_cnt_nsec;
+	unsigned int tx_base_unit_nsec;
+	unsigned int tx_gran_unit_nsec;
+	unsigned int tx_sleep_cnt;
+	unsigned int tx_min_activatetime;
+	/* RX Attributes */
+	unsigned int rx_filler_enable;
+	unsigned int rx_dif_p_nsec;
+	unsigned int rx_hibern8_wait_nsec;
+	unsigned int rx_base_unit_nsec;
+	unsigned int rx_gran_unit_nsec;
+	unsigned int rx_sleep_cnt;
+	unsigned int rx_stall_cnt;
+	unsigned int rx_hs_g1_sync_len_cap;
+	unsigned int rx_hs_g2_sync_len_cap;
+	unsigned int rx_hs_g3_sync_len_cap;
+	unsigned int rx_hs_g1_prep_sync_len_cap;
+	unsigned int rx_hs_g2_prep_sync_len_cap;
+	unsigned int rx_hs_g3_prep_sync_len_cap;
+	/* Common Attributes */
+	unsigned int cmn_pwm_clk_ctrl;
+	/* Internal Attributes */
+	unsigned int pa_dbg_option_suite;
+	/* Changeable Attributes */
+	unsigned int rx_adv_fine_gran_sup_en;
+	unsigned int rx_adv_fine_gran_step;
+	unsigned int rx_min_actv_time_cap;
+	unsigned int rx_hibern8_time_cap;
+	unsigned int rx_adv_min_actv_time_cap;
+	unsigned int rx_adv_hibern8_time_cap;
+	unsigned int pa_granularity;
+	unsigned int pa_tactivate;
+	unsigned int pa_hibern8time;
+};
+
+struct exynos_ufs_drv_data {
+	char *compatible;
+	struct exynos_ufs_uic_attr *uic_attr;
+	unsigned int quirks;
+	unsigned int opts;
+	/* SoC's specific operations */
+	int (*drv_init)(struct device *dev, struct exynos_ufs *ufs);
+	int (*pre_link)(struct exynos_ufs *ufs);
+	int (*post_link)(struct exynos_ufs *ufs);
+	int (*pre_pwr_change)(struct exynos_ufs *ufs, struct uic_pwr_mode *pwr);
+	int (*post_pwr_change)(struct exynos_ufs *ufs,
+				struct uic_pwr_mode *pwr);
+};
+
+struct ufs_phy_time_cfg {
+	u32 tx_linereset_p;
+	u32 tx_linereset_n;
+	u32 tx_high_z_cnt;
+	u32 tx_base_n_val;
+	u32 tx_gran_n_val;
+	u32 tx_sleep_cnt;
+	u32 rx_linereset;
+	u32 rx_hibern8_wait;
+	u32 rx_base_n_val;
+	u32 rx_gran_n_val;
+	u32 rx_sleep_cnt;
+	u32 rx_stall_cnt;
+};
+
+struct exynos_ufs {
+	struct ufs_hba *hba;
+	struct phy *phy;
+	void __iomem *reg_hci;
+	void __iomem *reg_unipro;
+	void __iomem *reg_ufsp;
+	struct clk *clk_hci_core;
+	struct clk *clk_unipro_main;
+	struct clk *clk_apb;
+	u32 pclk_rate;
+	u32 pclk_div;
+	u32 pclk_avail_min;
+	u32 pclk_avail_max;
+	u32 mclk_rate;
+	int avail_ln_rx;
+	int avail_ln_tx;
+	int rx_sel_idx;
+	struct uic_pwr_mode pwr_req;	/* requested power mode */
+	struct uic_pwr_mode pwr_act;	/* actual power mode */
+	struct ufs_phy_time_cfg t_cfg;
+	ktime_t entry_hibern8_t;
+	struct exynos_ufs_drv_data *drv_data;
+
+	u32 opts;
+#define EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL		BIT(0)
+#define EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB	BIT(1)
+#define EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL	BIT(2)
+#define EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX	BIT(3)
+#define EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER	BIT(4)
+};
+
+#define for_each_ufs_rx_lane(ufs, i) \
+	for (i = (ufs)->rx_sel_idx; \
+		i < (ufs)->rx_sel_idx + (ufs)->avail_ln_rx; i++)
+#define for_each_ufs_tx_lane(ufs, i) \
+	for (i = 0; i < (ufs)->avail_ln_tx; i++)
+
+#define EXYNOS_UFS_MMIO_FUNC(name)					  \
+static inline void name##_writel(struct exynos_ufs *ufs, u32 val, u32 reg)\
+{									  \
+	writel(val, ufs->reg_##name + reg);				  \
+}									  \
+									  \
+static inline u32 name##_readl(struct exynos_ufs *ufs, u32 reg)		  \
+{									  \
+	return readl(ufs->reg_##name + reg);				  \
+}
+
+EXYNOS_UFS_MMIO_FUNC(hci);
+EXYNOS_UFS_MMIO_FUNC(unipro);
+EXYNOS_UFS_MMIO_FUNC(ufsp);
+#undef EXYNOS_UFS_MMIO_FUNC
+
+extern long exynos_ufs_calc_time_cntr(struct exynos_ufs *, long);
+
+static inline void exynos_ufs_enable_ov_tm(struct ufs_hba *hba)
+{
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OV_TM), TRUE);
+}
+
+static inline void exynos_ufs_disable_ov_tm(struct ufs_hba *hba)
+{
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OV_TM), FALSE);
+}
+
+static inline void exynos_ufs_enable_dbg_mode(struct ufs_hba *hba)
+{
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), TRUE);
+}
+
+static inline void exynos_ufs_disable_dbg_mode(struct ufs_hba *hba)
+{
+	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), FALSE);
+}
+
+struct exynos_ufs_drv_data exynos_ufs_drvs;
+
+struct exynos_ufs_uic_attr exynos7_uic_attr = {
+	.tx_trailingclks		= 0x10,
+	.tx_dif_p_nsec			= 3000000,	/* unit: ns */
+	.tx_dif_n_nsec			= 1000000,	/* unit: ns */
+	.tx_high_z_cnt_nsec		= 20000,	/* unit: ns */
+	.tx_base_unit_nsec		= 100000,	/* unit: ns */
+	.tx_gran_unit_nsec		= 4000,		/* unit: ns */
+	.tx_sleep_cnt			= 1000,		/* unit: ns */
+	.tx_min_activatetime		= 0xa,
+	.rx_filler_enable		= 0x2,
+	.rx_dif_p_nsec			= 1000000,	/* unit: ns */
+	.rx_hibern8_wait_nsec		= 4000000,	/* unit: ns */
+	.rx_base_unit_nsec		= 100000,	/* unit: ns */
+	.rx_gran_unit_nsec		= 4000,		/* unit: ns */
+	.rx_sleep_cnt			= 1280,		/* unit: ns */
+	.rx_stall_cnt			= 320,		/* unit: ns */
+	.rx_hs_g1_sync_len_cap		= SYNC_LEN_COARSE(0xf),
+	.rx_hs_g2_sync_len_cap		= SYNC_LEN_COARSE(0xf),
+	.rx_hs_g3_sync_len_cap		= SYNC_LEN_COARSE(0xf),
+	.rx_hs_g1_prep_sync_len_cap	= PREP_LEN(0xf),
+	.rx_hs_g2_prep_sync_len_cap	= PREP_LEN(0xf),
+	.rx_hs_g3_prep_sync_len_cap	= PREP_LEN(0xf),
+	.pa_dbg_option_suite		= 0x30103,
+};
+#endif /* _UFS_EXYNOS_H_ */
diff --git a/drivers/scsi/ufs/unipro.h b/drivers/scsi/ufs/unipro.h
index 3dc4d8b76509..f441ab54829c 100644
--- a/drivers/scsi/ufs/unipro.h
+++ b/drivers/scsi/ufs/unipro.h
@@ -64,8 +64,25 @@
 #define CFGRXOVR4				0x00E9
 #define RXSQCTRL				0x00B5
 #define CFGRXOVR6				0x00BF
+#define RX_HS_G1_SYNC_LENGTH_CAP		0x008B
+#define RX_HS_G1_PREP_LENGTH_CAP		0x008C
+#define RX_HS_G2_SYNC_LENGTH_CAP		0x0094
+#define RX_HS_G3_SYNC_LENGTH_CAP		0x0095
+#define RX_HS_G2_PREP_LENGTH_CAP		0x0096
+#define RX_HS_G3_PREP_LENGTH_CAP		0x0097
+#define RX_ADV_GRANULARITY_CAP			0x0098
+#define RX_MIN_ACTIVATETIME_CAP			0x008F
+#define RX_HIBERN8TIME_CAP			0x0092
+#define RX_ADV_HIBERN8TIME_CAP			0x0099
+#define RX_ADV_MIN_ACTIVATETIME_CAP		0x009A
+
 
 #define is_mphy_tx_attr(attr)			(attr < RX_MODE)
+#define RX_ADV_FINE_GRAN_STEP(x)		((((x) & 0x3) << 1) | 0x1)
+#define SYNC_LEN_FINE(x)			((x) & 0x3F)
+#define SYNC_LEN_COARSE(x)			((1 << 6) | ((x) & 0x3F))
+#define PREP_LEN(x)				((x) & 0xF)
+
 #define RX_MIN_ACTIVATETIME_UNIT_US		100
 #define HIBERN8TIME_UNIT_US			100
 
@@ -124,6 +141,7 @@
 #define PA_PACPREQEOBTIMEOUT	0x1591
 #define PA_HIBERN8TIME		0x15A7
 #define PA_LOCALVERINFO		0x15A9
+#define PA_GRANULARITY		0x15AA
 #define PA_TACTIVATE		0x15A8
 #define PA_PACPFRAMECOUNT	0x15C0
 #define PA_PACPERRORCOUNT	0x15C1
@@ -181,6 +199,9 @@ enum {
 	UNCHANGED	= 7,
 };
 
+#define IS_UFS_PWR_MODE_HS(m)	(((m) == FAST_MODE) || ((m) == FASTAUTO_MODE))
+#define IS_UFS_PWR_MODE_PWM(m)	(((m) == SLOW_MODE) || ((m) == SLOWAUTO_MODE))
+
 /* PA TX/RX Frequency Series */
 enum {
 	PA_HS_MODE_A	= 1,
@@ -242,6 +263,11 @@ enum ufs_unipro_ver {
 #define DL_PEERTC1PRESENT	0x2066
 #define DL_PEERTC1RXINITCREVAL	0x2067
 
+/* Default value of L2 Timer */
+#define FC0PROTTIMEOUTVAL	8191
+#define TC0REPLAYTIMEOUTVAL	65535
+#define AFC0REQTIMEOUTVAL	32767
+
 /*
  * Network Layer Attributes
  */
@@ -284,4 +310,19 @@ enum {
 	TRUE,
 };
 
+/* CPort setting */
+#define E2EFC_ON	(1 << 0)
+#define E2EFC_OFF	(0 << 0)
+#define CSD_N_ON	(0 << 1)
+#define CSD_N_OFF	(1 << 1)
+#define CSV_N_ON	(0 << 2)
+#define CSV_N_OFF	(1 << 2)
+#define CPORT_DEF_FLAGS	(CSV_N_OFF | CSD_N_OFF | E2EFC_OFF)
+
+/* CPort connection state */
+enum {
+	CPORT_IDLE = 0,
+	CPORT_CONNECTED,
+};
+
 #endif /* _UNIPRO_H_ */
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
       [not found]   ` <CGME20200327171423epcas5p485d227f19e45999ad9b42b21d2864e4a@epcas5p4.samsung.com>
@ 2020-03-27 17:06     ` Alim Akhtar
  2020-03-28 13:30       ` Paweł Chmiel
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-03-27 17:06 UTC (permalink / raw)
  To: robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, Alim Akhtar, stanley.chu,
	linux-arm-kernel

Adding dt node foe UFS and UFS-PHY for exynos7 SoC.

Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
---
 .../boot/dts/exynos/exynos7-espresso.dts      | 16 +++++++
 arch/arm64/boot/dts/exynos/exynos7.dtsi       | 43 ++++++++++++++++++-
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
index 7af288fa9475..b59a0a32620a 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
+++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
@@ -406,6 +406,22 @@
 	};
 };
 
+&ufs {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
+	ufs,pwr-attr-mode = "FAST";
+	ufs,pwr-attr-lane = <2>;
+	ufs,pwr-attr-gear = <2>;
+	ufs,pwr-attr-hs-series = "HS_rate_b";
+	ufs-rx-adv-fine-gran-sup_en = <1>;
+	ufs-rx-adv-fine-gran-step = <3>;
+	ufs-rx-adv-min-activate-time-cap = <9>;
+	ufs-pa-granularity = <6>;
+	ufs-pa-tacctivate = <3>;
+	ufs-pa-hibern8time = <20>;
+};
+
 &usbdrd_phy {
 	vbus-supply = <&usb30_vbus_reg>;
 	vbus-boost-supply = <&usb3drd_boost_5v>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index 5558045637ac..9d16c90edd07 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -220,9 +220,14 @@
 			#clock-cells = <1>;
 			clocks = <&fin_pll>, <&clock_top1 DOUT_ACLK_FSYS1_200>,
 				 <&clock_top1 DOUT_SCLK_MMC0>,
-				 <&clock_top1 DOUT_SCLK_MMC1>;
+				 <&clock_top1 DOUT_SCLK_MMC1>,
+				 <&clock_top1 DOUT_SCLK_UFSUNIPRO20>,
+				 <&clock_top1 DOUT_SCLK_PHY_FSYS1>,
+				 <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>;
 			clock-names = "fin_pll", "dout_aclk_fsys1_200",
-				      "dout_sclk_mmc0", "dout_sclk_mmc1";
+				      "dout_sclk_mmc0", "dout_sclk_mmc1",
+				      "dout_sclk_ufsunipro20", "dout_sclk_phy_fsys1",
+				      "dout_sclk_phy_fsys1_26m";
 		};
 
 		serial_0: serial@13630000 {
@@ -601,6 +606,40 @@
 			};
 		};
 
+		ufs: ufs@15570000 {
+			compatible = "samsung,exynos7-ufs";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			reg = <0x15570000 0x100>,  /* 0: HCI standard */
+				<0x15570100 0x100>,  /* 1: Vendor specificed */
+				<0x15571000 0x200>,  /* 2: UNIPRO */
+				<0x15572000 0x300>;  /* 3: UFS protector */
+			reg-names = "hci", "vs_hci", "unipro", "ufsp";
+			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
+				<&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
+			clock-names = "core_clk", "sclk_unipro_main";
+			freq-table-hz = <0 0>, <0 0>;
+			pclk-freq-avail-range = <70000000 133000000>;
+			ufs,pwr-local-l2-timer = <8000 28000 20000>;
+			ufs,pwr-remote-l2-timer = <12000 32000 16000>;
+			phys = <&ufs_phy>;
+			phy-names = "ufs-phy";
+			status = "disabled";
+		};
+
+		ufs_phy: ufs-phy@0x15571800 {
+			compatible = "samsung,exynos7-ufs-phy";
+			reg = <0x15571800 0x240>;
+			reg-names = "phy-pma";
+			samsung,pmu-syscon = <&pmu_system_controller>;
+			#phy-cells = <0>;
+			clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
+				<&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
+			clock-names = "ref_clk_parent", "ref_clk";
+		};
+
 		usbdrd_phy: phy@15500000 {
 			compatible = "samsung,exynos7-usbdrd-phy";
 			reg = <0x15500000 0x100>;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* RE: [PATCH v4 4/5] scsi: ufs-exynos: add UFS host support for Exynos SoCs
  2020-03-27 17:06     ` [PATCH v4 4/5] scsi: ufs-exynos: add UFS host support for Exynos SoCs Alim Akhtar
@ 2020-03-28 11:28       ` Avri Altman
  2020-04-02 15:08         ` Alim Akhtar
  0 siblings, 1 reply; 22+ messages in thread
From: Avri Altman @ 2020-03-28 11:28 UTC (permalink / raw)
  To: Alim Akhtar, robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, cang, stanley.chu, linux-arm-kernel

Hi,

> +
> +long exynos_ufs_calc_time_cntr(struct exynos_ufs *ufs, long period)
> +{
> +       const int precise = 10;
> +       long pclk_rate = ufs->pclk_rate;
> +       long clk_period, fraction;
> +
> +       clk_period = UNIPRO_PCLK_PERIOD(ufs);
> +       fraction = ((NSEC_PER_SEC % pclk_rate) * precise) / pclk_rate;
> +
> +       return (period * precise) / ((clk_period * precise) + fraction);
> +}
This helper essentially calculates a factor f, and returns period x f.
Why not do that regardless of period?

> +extern long exynos_ufs_calc_time_cntr(struct exynos_ufs *, long);
Why this factor needed to be exported?
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-03-27 17:06     ` [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7 Alim Akhtar
@ 2020-03-28 13:30       ` Paweł Chmiel
  2020-03-28 15:35         ` Alim Akhtar
  0 siblings, 1 reply; 22+ messages in thread
From: Paweł Chmiel @ 2020-03-28 13:30 UTC (permalink / raw)
  To: Alim Akhtar, robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

On Fri, 2020-03-27 at 22:36 +0530, Alim Akhtar wrote:
> Adding dt node foe UFS and UFS-PHY for exynos7 SoC.
> 
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> ---
>  .../boot/dts/exynos/exynos7-espresso.dts      | 16 +++++++
>  arch/arm64/boot/dts/exynos/exynos7.dtsi       | 43 ++++++++++++++++++-
>  2 files changed, 57 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> index 7af288fa9475..b59a0a32620a 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> @@ -406,6 +406,22 @@
>  	};
>  };
>  
> +&ufs {
> +	status = "okay";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> +	ufs,pwr-attr-mode = "FAST";
> +	ufs,pwr-attr-lane = <2>;
> +	ufs,pwr-attr-gear = <2>;
> +	ufs,pwr-attr-hs-series = "HS_rate_b";
> +	ufs-rx-adv-fine-gran-sup_en = <1>;
> +	ufs-rx-adv-fine-gran-step = <3>;
> +	ufs-rx-adv-min-activate-time-cap = <9>;
> +	ufs-pa-granularity = <6>;
> +	ufs-pa-tacctivate = <3>;
> +	ufs-pa-hibern8time = <20>;
> +};
> +
>  &usbdrd_phy {
>  	vbus-supply = <&usb30_vbus_reg>;
>  	vbus-boost-supply = <&usb3drd_boost_5v>;
> diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> index 5558045637ac..9d16c90edd07 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> @@ -220,9 +220,14 @@
>  			#clock-cells = <1>;
>  			clocks = <&fin_pll>, <&clock_top1 DOUT_ACLK_FSYS1_200>,
>  				 <&clock_top1 DOUT_SCLK_MMC0>,
> -				 <&clock_top1 DOUT_SCLK_MMC1>;
> +				 <&clock_top1 DOUT_SCLK_MMC1>,
> +				 <&clock_top1 DOUT_SCLK_UFSUNIPRO20>,
> +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1>,
> +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>;
>  			clock-names = "fin_pll", "dout_aclk_fsys1_200",
> -				      "dout_sclk_mmc0", "dout_sclk_mmc1";
> +				      "dout_sclk_mmc0", "dout_sclk_mmc1",
> +				      "dout_sclk_ufsunipro20", "dout_sclk_phy_fsys1",
> +				      "dout_sclk_phy_fsys1_26m";
>  		};
>  
>  		serial_0: serial@13630000 {
> @@ -601,6 +606,40 @@
>  			};
>  		};
>  
> +		ufs: ufs@15570000 {
> +			compatible = "samsung,exynos7-ufs";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges;
> +			reg = <0x15570000 0x100>,  /* 0: HCI standard */
> +				<0x15570100 0x100>,  /* 1: Vendor specificed */
> +				<0x15571000 0x200>,  /* 2: UNIPRO */
> +				<0x15572000 0x300>;  /* 3: UFS protector */
> +			reg-names = "hci", "vs_hci", "unipro", "ufsp";
> +			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> +				<&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> +			clock-names = "core_clk", "sclk_unipro_main";
> +			freq-table-hz = <0 0>, <0 0>;
> +			pclk-freq-avail-range = <70000000 133000000>;
> +			ufs,pwr-local-l2-timer = <8000 28000 20000>;
> +			ufs,pwr-remote-l2-timer = <12000 32000 16000>;
> +			phys = <&ufs_phy>;
> +			phy-names = "ufs-phy";
> +			status = "disabled";
> +		};
> +
> +		ufs_phy: ufs-phy@0x15571800 {
> +			compatible = "samsung,exynos7-ufs-phy";
> +			reg = <0x15571800 0x240>;
> +			reg-names = "phy-pma";
> +			samsung,pmu-syscon = <&pmu_system_controller>;
> +			#phy-cells = <0>;
> +			clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
> +				<&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
> +			clock-names = "ref_clk_parent", "ref_clk";
Hi
Is this correct (aren't child and parent clock swapped)?
This will set MOUT_FSYS1_PHYCLK_SEL1 to be parent clock of
CLK_SCLK_PHY_FSYS1_26M.
I've tested this on Exynos7420 (which looks like can use the same clock
driver as exynos7) and after adding some debug code (because currently
we're not handling result of samsung_ufs_phy_clks_init) i got

samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: -22

On vendor sources for this device, driver was setting
CLK_SCLK_PHY_FSYS1_26M to be parent of MOUT_FSYS1_PHYCLK_SEL1, and then
it did run without error.

samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: 0

Also looking at clk-exynos7 driver seems to confirm this.

> +		};
> +
>  		usbdrd_phy: phy@15500000 {
>  			compatible = "samsung,exynos7-usbdrd-phy";
>  			reg = <0x15500000 0x100>;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-03-28 13:30       ` Paweł Chmiel
@ 2020-03-28 15:35         ` Alim Akhtar
  2020-03-28 17:46           ` Paweł Chmiel
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-03-28 15:35 UTC (permalink / raw)
  To: 'Paweł Chmiel', robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

Hi Pawel

> -----Original Message-----
> From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> Sent: 28 March 2020 19:00
> To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> 
> On Fri, 2020-03-27 at 22:36 +0530, Alim Akhtar wrote:
> > Adding dt node foe UFS and UFS-PHY for exynos7 SoC.
> >
> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > ---
> >  .../boot/dts/exynos/exynos7-espresso.dts      | 16 +++++++
> >  arch/arm64/boot/dts/exynos/exynos7.dtsi       | 43 ++++++++++++++++++-
> >  2 files changed, 57 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > index 7af288fa9475..b59a0a32620a 100644
> > --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > @@ -406,6 +406,22 @@
> >  	};
> >  };
> >
> > +&ufs {
> > +	status = "okay";
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> > +	ufs,pwr-attr-mode = "FAST";
> > +	ufs,pwr-attr-lane = <2>;
> > +	ufs,pwr-attr-gear = <2>;
> > +	ufs,pwr-attr-hs-series = "HS_rate_b";
> > +	ufs-rx-adv-fine-gran-sup_en = <1>;
> > +	ufs-rx-adv-fine-gran-step = <3>;
> > +	ufs-rx-adv-min-activate-time-cap = <9>;
> > +	ufs-pa-granularity = <6>;
> > +	ufs-pa-tacctivate = <3>;
> > +	ufs-pa-hibern8time = <20>;
> > +};
> > +
> >  &usbdrd_phy {
> >  	vbus-supply = <&usb30_vbus_reg>;
> >  	vbus-boost-supply = <&usb3drd_boost_5v>; diff --git
> > a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > index 5558045637ac..9d16c90edd07 100644
> > --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > @@ -220,9 +220,14 @@
> >  			#clock-cells = <1>;
> >  			clocks = <&fin_pll>, <&clock_top1
> DOUT_ACLK_FSYS1_200>,
> >  				 <&clock_top1 DOUT_SCLK_MMC0>,
> > -				 <&clock_top1 DOUT_SCLK_MMC1>;
> > +				 <&clock_top1 DOUT_SCLK_MMC1>,
> > +				 <&clock_top1 DOUT_SCLK_UFSUNIPRO20>,
> > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1>,
> > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>;
> >  			clock-names = "fin_pll", "dout_aclk_fsys1_200",
> > -				      "dout_sclk_mmc0", "dout_sclk_mmc1";
> > +				      "dout_sclk_mmc0", "dout_sclk_mmc1",
> > +				      "dout_sclk_ufsunipro20",
> "dout_sclk_phy_fsys1",
> > +				      "dout_sclk_phy_fsys1_26m";
> >  		};
> >
> >  		serial_0: serial@13630000 {
> > @@ -601,6 +606,40 @@
> >  			};
> >  		};
> >
> > +		ufs: ufs@15570000 {
> > +			compatible = "samsung,exynos7-ufs";
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +			ranges;
> > +			reg = <0x15570000 0x100>,  /* 0: HCI standard */
> > +				<0x15570100 0x100>,  /* 1: Vendor specificed
> */
> > +				<0x15571000 0x200>,  /* 2: UNIPRO */
> > +				<0x15572000 0x300>;  /* 3: UFS protector */
> > +			reg-names = "hci", "vs_hci", "unipro", "ufsp";
> > +			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> > +				<&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> > +			clock-names = "core_clk", "sclk_unipro_main";
> > +			freq-table-hz = <0 0>, <0 0>;
> > +			pclk-freq-avail-range = <70000000 133000000>;
> > +			ufs,pwr-local-l2-timer = <8000 28000 20000>;
> > +			ufs,pwr-remote-l2-timer = <12000 32000 16000>;
> > +			phys = <&ufs_phy>;
> > +			phy-names = "ufs-phy";
> > +			status = "disabled";
> > +		};
> > +
> > +		ufs_phy: ufs-phy@0x15571800 {
> > +			compatible = "samsung,exynos7-ufs-phy";
> > +			reg = <0x15571800 0x240>;
> > +			reg-names = "phy-pma";
> > +			samsung,pmu-syscon = <&pmu_system_controller>;
> > +			#phy-cells = <0>;
> > +			clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
> > +				<&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
> > +			clock-names = "ref_clk_parent", "ref_clk";
> Hi
> Is this correct (aren't child and parent clock swapped)?
> This will set MOUT_FSYS1_PHYCLK_SEL1 to be parent clock of
> CLK_SCLK_PHY_FSYS1_26M.

Looks like in one of my rebase it got swap, will correct it.  Thanks for pointing out.

> I've tested this on Exynos7420 (which looks like can use the same clock driver as
> exynos7) and after adding some debug code (because currently we're not
> handling result of samsung_ufs_phy_clks_init) i got
> 
> samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: -22
> 
I will check if I overlooked this error.
> On vendor sources for this device, driver was setting CLK_SCLK_PHY_FSYS1_26M
> to be parent of MOUT_FSYS1_PHYCLK_SEL1, and then it did run without error.
> 
> samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: 0
> 
With this change, does linkup worked for you?

> Also looking at clk-exynos7 driver seems to confirm this.
> 
> > +		};
> > +
> >  		usbdrd_phy: phy@15500000 {
> >  			compatible = "samsung,exynos7-usbdrd-phy";
> >  			reg = <0x15500000 0x100>;




_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-03-28 15:35         ` Alim Akhtar
@ 2020-03-28 17:46           ` Paweł Chmiel
  2020-03-29 15:35             ` Alim Akhtar
  0 siblings, 1 reply; 22+ messages in thread
From: Paweł Chmiel @ 2020-03-28 17:46 UTC (permalink / raw)
  To: Alim Akhtar, robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

On Sat, 2020-03-28 at 21:05 +0530, Alim Akhtar wrote:
> Hi Pawel
> 
> > -----Original Message-----
> > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > Sent: 28 March 2020 19:00
> > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> > kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> > cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > 
> > On Fri, 2020-03-27 at 22:36 +0530, Alim Akhtar wrote:
> > > Adding dt node foe UFS and UFS-PHY for exynos7 SoC.
> > > 
> > > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > > ---
> > >  .../boot/dts/exynos/exynos7-espresso.dts      | 16 +++++++
> > >  arch/arm64/boot/dts/exynos/exynos7.dtsi       | 43 ++++++++++++++++++-
> > >  2 files changed, 57 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > index 7af288fa9475..b59a0a32620a 100644
> > > --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > @@ -406,6 +406,22 @@
> > >  	};
> > >  };
> > > 
> > > +&ufs {
> > > +	status = "okay";
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> > > +	ufs,pwr-attr-mode = "FAST";
> > > +	ufs,pwr-attr-lane = <2>;
> > > +	ufs,pwr-attr-gear = <2>;
> > > +	ufs,pwr-attr-hs-series = "HS_rate_b";
> > > +	ufs-rx-adv-fine-gran-sup_en = <1>;
> > > +	ufs-rx-adv-fine-gran-step = <3>;
> > > +	ufs-rx-adv-min-activate-time-cap = <9>;
> > > +	ufs-pa-granularity = <6>;
> > > +	ufs-pa-tacctivate = <3>;
> > > +	ufs-pa-hibern8time = <20>;
> > > +};
> > > +
> > >  &usbdrd_phy {
> > >  	vbus-supply = <&usb30_vbus_reg>;
> > >  	vbus-boost-supply = <&usb3drd_boost_5v>; diff --git
> > > a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > index 5558045637ac..9d16c90edd07 100644
> > > --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > @@ -220,9 +220,14 @@
> > >  			#clock-cells = <1>;
> > >  			clocks = <&fin_pll>, <&clock_top1
> > DOUT_ACLK_FSYS1_200>,
> > >  				 <&clock_top1 DOUT_SCLK_MMC0>,
> > > -				 <&clock_top1 DOUT_SCLK_MMC1>;
> > > +				 <&clock_top1 DOUT_SCLK_MMC1>,
> > > +				 <&clock_top1 DOUT_SCLK_UFSUNIPRO20>,
> > > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1>,
> > > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>;
> > >  			clock-names = "fin_pll", "dout_aclk_fsys1_200",
> > > -				      "dout_sclk_mmc0", "dout_sclk_mmc1";
> > > +				      "dout_sclk_mmc0", "dout_sclk_mmc1",
> > > +				      "dout_sclk_ufsunipro20",
> > "dout_sclk_phy_fsys1",
> > > +				      "dout_sclk_phy_fsys1_26m";
> > >  		};
> > > 
> > >  		serial_0: serial@13630000 {
> > > @@ -601,6 +606,40 @@
> > >  			};
> > >  		};
> > > 
> > > +		ufs: ufs@15570000 {
> > > +			compatible = "samsung,exynos7-ufs";
> > > +			#address-cells = <1>;
> > > +			#size-cells = <1>;
> > > +			ranges;
> > > +			reg = <0x15570000 0x100>,  /* 0: HCI standard */
> > > +				<0x15570100 0x100>,  /* 1: Vendor specificed
> > */
> > > +				<0x15571000 0x200>,  /* 2: UNIPRO */
> > > +				<0x15572000 0x300>;  /* 3: UFS protector */
> > > +			reg-names = "hci", "vs_hci", "unipro", "ufsp";
> > > +			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> > > +			clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> > > +				<&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> > > +			clock-names = "core_clk", "sclk_unipro_main";
> > > +			freq-table-hz = <0 0>, <0 0>;
> > > +			pclk-freq-avail-range = <70000000 133000000>;
> > > +			ufs,pwr-local-l2-timer = <8000 28000 20000>;
> > > +			ufs,pwr-remote-l2-timer = <12000 32000 16000>;
> > > +			phys = <&ufs_phy>;
> > > +			phy-names = "ufs-phy";
> > > +			status = "disabled";
> > > +		};
> > > +
> > > +		ufs_phy: ufs-phy@0x15571800 {
> > > +			compatible = "samsung,exynos7-ufs-phy";
> > > +			reg = <0x15571800 0x240>;
> > > +			reg-names = "phy-pma";
> > > +			samsung,pmu-syscon = <&pmu_system_controller>;
> > > +			#phy-cells = <0>;
> > > +			clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
> > > +				<&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
> > > +			clock-names = "ref_clk_parent", "ref_clk";
> > Hi
> > Is this correct (aren't child and parent clock swapped)?
> > This will set MOUT_FSYS1_PHYCLK_SEL1 to be parent clock of
> > CLK_SCLK_PHY_FSYS1_26M.
> 
> Looks like in one of my rebase it got swap, will correct it.  Thanks for pointing out.
> 
> > I've tested this on Exynos7420 (which looks like can use the same clock driver as
> > exynos7) and after adding some debug code (because currently we're not
> > handling result of samsung_ufs_phy_clks_init) i got
> > 
> > samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: -22
> > 
> I will check if I overlooked this error.
> > On vendor sources for this device, driver was setting CLK_SCLK_PHY_FSYS1_26M
> > to be parent of MOUT_FSYS1_PHYCLK_SEL1, and then it did run without error.
> > 
> > samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: 0
> > 
> With this change, does linkup worked for you?
Hi
Sadly not yet, so someone needs to check it on different hw.

I've added some debug code to ufshcd and it looks like it fails (in my
case) at ufshcd_dme_link_startup which returns 1 (because
ufshcd_wait_for_uic_cmd returns 1). The same for second retry and at
third retry it's getting -110 from ufshcd_wait_for_uic_cmd.

Need to check:
- in vendor there was 10 clocks used by ufs/ufs-phy (where this driver
uses 4)
- if calibration is the same in this driver vs vendor

Maybe it's because of missing EXYNOS FMP Driver (my device has
secureos) and/or some missing smc calls (like in case of smu config)?
> 
> > Also looking at clk-exynos7 driver seems to confirm this.
> > 
> > > +		};
> > > +
> > >  		usbdrd_phy: phy@15500000 {
> > >  			compatible = "samsung,exynos7-usbdrd-phy";
> > >  			reg = <0x15500000 0x100>;
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-03-28 17:46           ` Paweł Chmiel
@ 2020-03-29 15:35             ` Alim Akhtar
  2020-04-03 16:52               ` Paweł Chmiel
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-03-29 15:35 UTC (permalink / raw)
  To: 'Paweł Chmiel', robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

Hi Pawel

> -----Original Message-----
> From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> Sent: 28 March 2020 23:17
> To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> 
> On Sat, 2020-03-28 at 21:05 +0530, Alim Akhtar wrote:
> > Hi Pawel
> >
> > > -----Original Message-----
> > > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > > Sent: 28 March 2020 19:00
> > > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > > Cc: krzk@kernel.org; avri.altman@wdc.com;
> > > martin.petersen@oracle.com; kwmad.kim@samsung.com;
> > > stanley.chu@mediatek.com; cang@codeaurora.org;
> > > linux-samsung-soc@vger.kernel.org; linux-arm-
> > > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > >
> > > On Fri, 2020-03-27 at 22:36 +0530, Alim Akhtar wrote:
> > > > Adding dt node foe UFS and UFS-PHY for exynos7 SoC.
> > > >
> > > > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > > > ---
> > > >  .../boot/dts/exynos/exynos7-espresso.dts      | 16 +++++++
> > > >  arch/arm64/boot/dts/exynos/exynos7.dtsi       | 43 ++++++++++++++++++-
> > > >  2 files changed, 57 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > index 7af288fa9475..b59a0a32620a 100644
> > > > --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > @@ -406,6 +406,22 @@
> > > >  	};
> > > >  };
> > > >
> > > > +&ufs {
> > > > +	status = "okay";
> > > > +	pinctrl-names = "default";
> > > > +	pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> > > > +	ufs,pwr-attr-mode = "FAST";
> > > > +	ufs,pwr-attr-lane = <2>;
> > > > +	ufs,pwr-attr-gear = <2>;
> > > > +	ufs,pwr-attr-hs-series = "HS_rate_b";
> > > > +	ufs-rx-adv-fine-gran-sup_en = <1>;
> > > > +	ufs-rx-adv-fine-gran-step = <3>;
> > > > +	ufs-rx-adv-min-activate-time-cap = <9>;
> > > > +	ufs-pa-granularity = <6>;
> > > > +	ufs-pa-tacctivate = <3>;
> > > > +	ufs-pa-hibern8time = <20>;
> > > > +};
> > > > +
> > > >  &usbdrd_phy {
> > > >  	vbus-supply = <&usb30_vbus_reg>;
> > > >  	vbus-boost-supply = <&usb3drd_boost_5v>; diff --git
> > > > a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > index 5558045637ac..9d16c90edd07 100644
> > > > --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > @@ -220,9 +220,14 @@
> > > >  			#clock-cells = <1>;
> > > >  			clocks = <&fin_pll>, <&clock_top1
> > > DOUT_ACLK_FSYS1_200>,
> > > >  				 <&clock_top1 DOUT_SCLK_MMC0>,
> > > > -				 <&clock_top1 DOUT_SCLK_MMC1>;
> > > > +				 <&clock_top1 DOUT_SCLK_MMC1>,
> > > > +				 <&clock_top1 DOUT_SCLK_UFSUNIPRO20>,
> > > > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1>,
> > > > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>;
> > > >  			clock-names = "fin_pll", "dout_aclk_fsys1_200",
> > > > -				      "dout_sclk_mmc0", "dout_sclk_mmc1";
> > > > +				      "dout_sclk_mmc0", "dout_sclk_mmc1",
> > > > +				      "dout_sclk_ufsunipro20",
> > > "dout_sclk_phy_fsys1",
> > > > +				      "dout_sclk_phy_fsys1_26m";
> > > >  		};
> > > >
> > > >  		serial_0: serial@13630000 {
> > > > @@ -601,6 +606,40 @@
> > > >  			};
> > > >  		};
> > > >
> > > > +		ufs: ufs@15570000 {
> > > > +			compatible = "samsung,exynos7-ufs";
> > > > +			#address-cells = <1>;
> > > > +			#size-cells = <1>;
> > > > +			ranges;
> > > > +			reg = <0x15570000 0x100>,  /* 0: HCI standard */
> > > > +				<0x15570100 0x100>,  /* 1: Vendor specificed
> > > */
> > > > +				<0x15571000 0x200>,  /* 2: UNIPRO */
> > > > +				<0x15572000 0x300>;  /* 3: UFS protector */
> > > > +			reg-names = "hci", "vs_hci", "unipro", "ufsp";
> > > > +			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> > > > +			clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> > > > +				<&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> > > > +			clock-names = "core_clk", "sclk_unipro_main";
> > > > +			freq-table-hz = <0 0>, <0 0>;
> > > > +			pclk-freq-avail-range = <70000000 133000000>;
> > > > +			ufs,pwr-local-l2-timer = <8000 28000 20000>;
> > > > +			ufs,pwr-remote-l2-timer = <12000 32000 16000>;
> > > > +			phys = <&ufs_phy>;
> > > > +			phy-names = "ufs-phy";
> > > > +			status = "disabled";
> > > > +		};
> > > > +
> > > > +		ufs_phy: ufs-phy@0x15571800 {
> > > > +			compatible = "samsung,exynos7-ufs-phy";
> > > > +			reg = <0x15571800 0x240>;
> > > > +			reg-names = "phy-pma";
> > > > +			samsung,pmu-syscon = <&pmu_system_controller>;
> > > > +			#phy-cells = <0>;
> > > > +			clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
> > > > +				<&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
> > > > +			clock-names = "ref_clk_parent", "ref_clk";
> > > Hi
> > > Is this correct (aren't child and parent clock swapped)?
> > > This will set MOUT_FSYS1_PHYCLK_SEL1 to be parent clock of
> > > CLK_SCLK_PHY_FSYS1_26M.
> >
> > Looks like in one of my rebase it got swap, will correct it.  Thanks for pointing
> out.
> >
> > > I've tested this on Exynos7420 (which looks like can use the same
> > > clock driver as
> > > exynos7) and after adding some debug code (because currently we're
> > > not handling result of samsung_ufs_phy_clks_init) i got
> > >
> > > samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: -22
> > >
> > I will check if I overlooked this error.
> > > On vendor sources for this device, driver was setting
> > > CLK_SCLK_PHY_FSYS1_26M to be parent of MOUT_FSYS1_PHYCLK_SEL1,
> and then it did run without error.
> > >
> > > samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: 0
> > >
> > With this change, does linkup worked for you?
> Hi
> Sadly not yet, so someone needs to check it on different hw.
> 
> I've added some debug code to ufshcd and it looks like it fails (in my
> case) at ufshcd_dme_link_startup which returns 1 (because
> ufshcd_wait_for_uic_cmd returns 1). The same for second retry and at third
> retry it's getting -110 from ufshcd_wait_for_uic_cmd.
> 
Mostly device is not responding to any UIC commands.

> Need to check:
> - in vendor there was 10 clocks used by ufs/ufs-phy (where this driver uses 4)
> - if calibration is the same in this driver vs vendor
> 
All clocks are not mandatory, what I have mentioned is only UFS HCI core clock, unipro clock and MPHY clocks.

> Maybe it's because of missing EXYNOS FMP Driver (my device has
> secureos) and/or some missing smc calls (like in case of smu config)?
FMP will come into picture a little later, it does not affect _link_startup though.
SMU does matter, so make sure SMU is by passed initially.

Another think that comes into my mind is, if possible just disabled PMIC (intension is to keep all the rails __always_on__)
The reason is sometime UFS_RST_N which is hooked to RESET_N of the UFS device is also controlled via one of the PMIC LDO.
(In your case I don't know which LDO, so keep all the rails always ON).
Also cross check if you have these gpios configured properly.
pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
Give it a try.


> >
> > > Also looking at clk-exynos7 driver seems to confirm this.
> > >
> > > > +		};
> > > > +
> > > >  		usbdrd_phy: phy@15500000 {
> > > >  			compatible = "samsung,exynos7-usbdrd-phy";
> > > >  			reg = <0x15500000 0x100>;
> >
> >




_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v4 4/5] scsi: ufs-exynos: add UFS host support for Exynos SoCs
  2020-03-28 11:28       ` Avri Altman
@ 2020-04-02 15:08         ` Alim Akhtar
  0 siblings, 0 replies; 22+ messages in thread
From: Alim Akhtar @ 2020-04-02 15:08 UTC (permalink / raw)
  To: 'Avri Altman', robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, cang, stanley.chu, linux-arm-kernel

Hi Avri

> -----Original Message-----
> From: Avri Altman <Avri.Altman@wdc.com>
> Sent: 28 March 2020 16:58
> To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> Cc: krzk@kernel.org; martin.petersen@oracle.com; kwmad.kim@samsung.com;
> stanley.chu@mediatek.com; cang@codeaurora.org; linux-samsung-
> soc@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org
> Subject: RE: [PATCH v4 4/5] scsi: ufs-exynos: add UFS host support for Exynos
> SoCs
> 
> Hi,
> 
> > +
> > +long exynos_ufs_calc_time_cntr(struct exynos_ufs *ufs, long period) {
> > +       const int precise = 10;
> > +       long pclk_rate = ufs->pclk_rate;
> > +       long clk_period, fraction;
> > +
> > +       clk_period = UNIPRO_PCLK_PERIOD(ufs);
> > +       fraction = ((NSEC_PER_SEC % pclk_rate) * precise) / pclk_rate;
> > +
> > +       return (period * precise) / ((clk_period * precise) +
> > +fraction); }
> This helper essentially calculates a factor f, and returns period x f.
> Why not do that regardless of period?
> 
The period can be different for different timing attributes, so this helper function takes the period and returns the timer counter value based on the pclk_rate. 

> > +extern long exynos_ufs_calc_time_cntr(struct exynos_ufs *, long);
> Why this factor needed to be exported?
Yes, not needed, will correct this in next version, which I am planning to post soon.
Thanks for your time and review, let me know if you have more inputs.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-03-29 15:35             ` Alim Akhtar
@ 2020-04-03 16:52               ` Paweł Chmiel
  2020-04-04 18:15                 ` Alim Akhtar
  0 siblings, 1 reply; 22+ messages in thread
From: Paweł Chmiel @ 2020-04-03 16:52 UTC (permalink / raw)
  To: Alim Akhtar, robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

On Sun, 2020-03-29 at 21:05 +0530, Alim Akhtar wrote:
> Hi Pawel
> 
> > -----Original Message-----
> > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > Sent: 28 March 2020 23:17
> > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> > kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> > cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > 
> > On Sat, 2020-03-28 at 21:05 +0530, Alim Akhtar wrote:
> > > Hi Pawel
> > > 
> > > > -----Original Message-----
> > > > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > > > Sent: 28 March 2020 19:00
> > > > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > > > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > > > Cc: krzk@kernel.org; avri.altman@wdc.com;
> > > > martin.petersen@oracle.com; kwmad.kim@samsung.com;
> > > > stanley.chu@mediatek.com; cang@codeaurora.org;
> > > > linux-samsung-soc@vger.kernel.org; linux-arm-
> > > > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > > > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > > > 
> > > > On Fri, 2020-03-27 at 22:36 +0530, Alim Akhtar wrote:
> > > > > Adding dt node foe UFS and UFS-PHY for exynos7 SoC.
> > > > > 
> > > > > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > > > > ---
> > > > >  .../boot/dts/exynos/exynos7-espresso.dts      | 16 +++++++
> > > > >  arch/arm64/boot/dts/exynos/exynos7.dtsi       | 43 ++++++++++++++++++-
> > > > >  2 files changed, 57 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > > b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > > index 7af288fa9475..b59a0a32620a 100644
> > > > > --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > > +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> > > > > @@ -406,6 +406,22 @@
> > > > >  	};
> > > > >  };
> > > > > 
> > > > > +&ufs {
> > > > > +	status = "okay";
> > > > > +	pinctrl-names = "default";
> > > > > +	pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> > > > > +	ufs,pwr-attr-mode = "FAST";
> > > > > +	ufs,pwr-attr-lane = <2>;
> > > > > +	ufs,pwr-attr-gear = <2>;
> > > > > +	ufs,pwr-attr-hs-series = "HS_rate_b";
> > > > > +	ufs-rx-adv-fine-gran-sup_en = <1>;
> > > > > +	ufs-rx-adv-fine-gran-step = <3>;
> > > > > +	ufs-rx-adv-min-activate-time-cap = <9>;
> > > > > +	ufs-pa-granularity = <6>;
> > > > > +	ufs-pa-tacctivate = <3>;
> > > > > +	ufs-pa-hibern8time = <20>;
> > > > > +};
> > > > > +
> > > > >  &usbdrd_phy {
> > > > >  	vbus-supply = <&usb30_vbus_reg>;
> > > > >  	vbus-boost-supply = <&usb3drd_boost_5v>; diff --git
> > > > > a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > > b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > > index 5558045637ac..9d16c90edd07 100644
> > > > > --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > > +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> > > > > @@ -220,9 +220,14 @@
> > > > >  			#clock-cells = <1>;
> > > > >  			clocks = <&fin_pll>, <&clock_top1
> > > > DOUT_ACLK_FSYS1_200>,
> > > > >  				 <&clock_top1 DOUT_SCLK_MMC0>,
> > > > > -				 <&clock_top1 DOUT_SCLK_MMC1>;
> > > > > +				 <&clock_top1 DOUT_SCLK_MMC1>,
> > > > > +				 <&clock_top1 DOUT_SCLK_UFSUNIPRO20>,
> > > > > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1>,
> > > > > +				 <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>;
> > > > >  			clock-names = "fin_pll", "dout_aclk_fsys1_200",
> > > > > -				      "dout_sclk_mmc0", "dout_sclk_mmc1";
> > > > > +				      "dout_sclk_mmc0", "dout_sclk_mmc1",
> > > > > +				      "dout_sclk_ufsunipro20",
> > > > "dout_sclk_phy_fsys1",
> > > > > +				      "dout_sclk_phy_fsys1_26m";
> > > > >  		};
> > > > > 
> > > > >  		serial_0: serial@13630000 {
> > > > > @@ -601,6 +606,40 @@
> > > > >  			};
> > > > >  		};
> > > > > 
> > > > > +		ufs: ufs@15570000 {
> > > > > +			compatible = "samsung,exynos7-ufs";
> > > > > +			#address-cells = <1>;
> > > > > +			#size-cells = <1>;
> > > > > +			ranges;
> > > > > +			reg = <0x15570000 0x100>,  /* 0: HCI standard */
> > > > > +				<0x15570100 0x100>,  /* 1: Vendor specificed
> > > > */
> > > > > +				<0x15571000 0x200>,  /* 2: UNIPRO */
> > > > > +				<0x15572000 0x300>;  /* 3: UFS protector */
> > > > > +			reg-names = "hci", "vs_hci", "unipro", "ufsp";
> > > > > +			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
> > > > > +			clocks = <&clock_fsys1 ACLK_UFS20_LINK>,
> > > > > +				<&clock_fsys1 SCLK_UFSUNIPRO20_USER>;
> > > > > +			clock-names = "core_clk", "sclk_unipro_main";
> > > > > +			freq-table-hz = <0 0>, <0 0>;
> > > > > +			pclk-freq-avail-range = <70000000 133000000>;
> > > > > +			ufs,pwr-local-l2-timer = <8000 28000 20000>;
> > > > > +			ufs,pwr-remote-l2-timer = <12000 32000 16000>;
> > > > > +			phys = <&ufs_phy>;
> > > > > +			phy-names = "ufs-phy";
> > > > > +			status = "disabled";
> > > > > +		};
> > > > > +
> > > > > +		ufs_phy: ufs-phy@0x15571800 {
> > > > > +			compatible = "samsung,exynos7-ufs-phy";
> > > > > +			reg = <0x15571800 0x240>;
> > > > > +			reg-names = "phy-pma";
> > > > > +			samsung,pmu-syscon = <&pmu_system_controller>;
> > > > > +			#phy-cells = <0>;
> > > > > +			clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
> > > > > +				<&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
> > > > > +			clock-names = "ref_clk_parent", "ref_clk";
> > > > Hi
> > > > Is this correct (aren't child and parent clock swapped)?
> > > > This will set MOUT_FSYS1_PHYCLK_SEL1 to be parent clock of
> > > > CLK_SCLK_PHY_FSYS1_26M.
> > > 
> > > Looks like in one of my rebase it got swap, will correct it.  Thanks for pointing
> > out.
> > > > I've tested this on Exynos7420 (which looks like can use the same
> > > > clock driver as
> > > > exynos7) and after adding some debug code (because currently we're
> > > > not handling result of samsung_ufs_phy_clks_init) i got
> > > > 
> > > > samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: -22
> > > > 
> > > I will check if I overlooked this error.
> > > > On vendor sources for this device, driver was setting
> > > > CLK_SCLK_PHY_FSYS1_26M to be parent of MOUT_FSYS1_PHYCLK_SEL1,
> > and then it did run without error.
> > > > samsung-ufs-phy 15571800.ufs-phy: clk_set_parent result: 0
> > > > 
> > > With this change, does linkup worked for you?
> > Hi
> > Sadly not yet, so someone needs to check it on different hw.
> > 
> > I've added some debug code to ufshcd and it looks like it fails (in my
> > case) at ufshcd_dme_link_startup which returns 1 (because
> > ufshcd_wait_for_uic_cmd returns 1). The same for second retry and at third
> > retry it's getting -110 from ufshcd_wait_for_uic_cmd.
> > 
> Mostly device is not responding to any UIC commands.
> 
> > Need to check:
> > - in vendor there was 10 clocks used by ufs/ufs-phy (where this driver uses 4)
> > - if calibration is the same in this driver vs vendor
> > 
> All clocks are not mandatory, what I have mentioned is only UFS HCI core clock, unipro clock and MPHY clocks.
> 
> > Maybe it's because of missing EXYNOS FMP Driver (my device has
> > secureos) and/or some missing smc calls (like in case of smu config)?
> FMP will come into picture a little later, it does not affect _link_startup though.
> SMU does matter, so make sure SMU is by passed initially.
> 
> Another think that comes into my mind is, if possible just disabled PMIC (intension is to keep all the rails __always_on__)
> The reason is sometime UFS_RST_N which is hooked to RESET_N of the UFS device is also controlled via one of the PMIC LDO.
> (In your case I don't know which LDO, so keep all the rails always ON).
> Also cross check if you have these gpios configured properly.
> pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
> Give it a try.
Hi Alim

Looking at vendor sources, my device is using the same gpios for
urfs_rst_n and ufs_refclk_out like Espresso (with one difference -
ufs_rst_n shouldn't be pulled up).

About regulators (it would be easier if dts would have all regulators).
It's also using s2mps15 as Espresso, but it vendor dts had only 8 (of
10 possible bucks, one missing was for UFS) and 14 ldos (of 27
possible), where almost all rails are connected to something.

I'm wondering how it's working on Espresso, because when adding correct
regulators for ufs (vccq = buck10 from s2mps15, always enabled for
testing plus vccq2 and vccq = two regulators enabled by one gpio,
enabled at boot by firmware), ufs wasn't still working because it was
then failing at defer probe (s2mps15 was probed after ufs)

[    0.962482] exynos-ufshc 15570000.ufs: ufshcd_get_vreg: vccq get
failed, err=-517

After that boot would just stop/hang.

After making a "dirty fix" by making s2mps15 regulator driver use
subsys_initcall (like in vendor sources) and ufs late_initcall (to give
it more time to setup and get it working and solve it later),
i had to mark following clocks as CLK_IGNORE_UNUSED to be able to bring
link up (it replicates setting done by vendor kernel, which enables
them on boot):
- "phyclk_ufs20_rx1_symbol_user"
- "phyclk_ufs20_rx0_symbol_user"
- "phyclk_ufs20_tx0_symbol_user"

Now it's able to bring both device and link, but it fails at
ufshcd_uic_change_pwr_mode.

[    1.411547] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
core_clk, rate: 100000000
[    1.419698] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
sclk_unipro_main, rate: 167000000
[    1.428550] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
core_clk enabled
[    1.436200] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
sclk_unipro_main enabled
[    1.445704] scsi host0: ufshcd
[    1.465684] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate =
0
[    2.023699] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
0x1fff error code 1
[    2.023846] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
0x1fff failed 0 retries
[    2.024025] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
0xffff error code 1
[    2.025457] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
0xffff failed 0 retries
[    2.033777] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
0x7fff error code 1
[    2.041607] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
0x7fff failed 0 retries
[    2.067809] exynos-ufshc 15570000.ufs: pwr ctrl cmd 0x2 failed, host
upmcrs:0x5
[    2.067953] exynos-ufshc 15570000.ufs: UFS Host state=0
[    2.068056] exynos-ufshc 15570000.ufs: outstanding reqs=0x0
tasks=0x0
[    2.068759] exynos-ufshc 15570000.ufs: saved_err=0x0,
saved_uic_err=0x0
[    2.075368] exynos-ufshc 15570000.ufs: Device power mode=1, UIC link
state=1
[    2.082392] exynos-ufshc 15570000.ufs: PM in progress=0, sys.
suspended=0
[    2.089158] exynos-ufshc 15570000.ufs: Auto BKOPS=0, Host self-
block=0
[    2.095667] exynos-ufshc 15570000.ufs: Clk gate=1
[    2.100354] exynos-ufshc 15570000.ufs: error handling flags=0x0,
req. abort count=0
[    2.107987] exynos-ufshc 15570000.ufs: Host capabilities=0x383ff0f,
caps=0x0
[    2.115018] exynos-ufshc 15570000.ufs: quirks=0x780, dev.
quirks=0xc4
[    2.121443] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate =
0
[    2.133960] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
[    2.140268] host_regs: 00000010: 00000101 00007fce 00000000 00000000
[    2.146604] host_regs: 00000020: 00000000 00030a75 00000000 00000000
[    2.152940] host_regs: 00000030: 0000050f 00000000 80000010 00000000
[    2.159271] host_regs: 00000040: 00000000 00000000 00000000 00000000
[    2.165609] host_regs: 00000050: f9587000 00000000 00000000 00000000
[    2.171944] host_regs: 00000060: 00000001 00000000 00000000 00000000
[    2.178278] host_regs: 00000070: f958a000 00000000 00000000 00000000
[    2.184609] host_regs: 00000080: 00000001 00000000 00000000 00000000
[    2.190945] host_regs: 00000090: 00000002 15710000 00000000 00000000
[    2.197282] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
hba->capabilities = 0x383ff0f
[    2.205869] exynos-ufshc 15570000.ufs: hba->outstanding_reqs = 0x0,
hba->outstanding_tasks = 0x0
[    2.214636] exynos-ufshc 15570000.ufs: last_hibern8_exit_tstamp at 0
us, hibern8_exit_cnt = 0
[    2.223141] exynos-ufshc 15570000.ufs: No record of pa_err
[    2.228606] exynos-ufshc 15570000.ufs: No record of dl_err
[    2.234071] exynos-ufshc 15570000.ufs: No record of nl_err
[    2.239540] exynos-ufshc 15570000.ufs: No record of tl_err
[    2.245007] exynos-ufshc 15570000.ufs: No record of dme_err
[    2.250558] exynos-ufshc 15570000.ufs: No record of auto_hibern8_err
[    2.256895] exynos-ufshc 15570000.ufs: No record of fatal_err
[    2.262624] exynos-ufshc 15570000.ufs: No record of
link_startup_fail
[    2.269044] exynos-ufshc 15570000.ufs: No record of resume_fail
[    2.274942] exynos-ufshc 15570000.ufs: No record of suspend_fail
[    2.280931] exynos-ufshc 15570000.ufs: No record of dev_reset
[    2.286659] exynos-ufshc 15570000.ufs: No record of host_reset
[    2.292475] exynos-ufshc 15570000.ufs: No record of task_abort
[    2.298290] exynos-ufshc 15570000.ufs: ufshcd_change_power_mode:
power mode change failed 5
[    2.306619] exynos-ufshc 15570000.ufs: ufshcd_probe_hba: Failed
setting power mode, err = 5
[    2.315144] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
core_clk disabled

And here boot would just stop/hang.

Thanks for all hints.

> 
> 
> > > > Also looking at clk-exynos7 driver seems to confirm this.
> > > > 
> > > > > +		};
> > > > > +
> > > > >  		usbdrd_phy: phy@15500000 {
> > > > >  			compatible = "samsung,exynos7-usbdrd-phy";
> > > > >  			reg = <0x15500000 0x100>;
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-04-03 16:52               ` Paweł Chmiel
@ 2020-04-04 18:15                 ` Alim Akhtar
  2020-04-04 19:33                   ` Paweł Chmiel
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-04-04 18:15 UTC (permalink / raw)
  To: 'Paweł Chmiel', robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 8139 bytes --]

Hi Pawel,

> -----Original Message-----
> From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> Sent: 03 April 2020 22:22
> To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> 
> Hi Alim
> 
> Looking at vendor sources, my device is using the same gpios for
> urfs_rst_n and ufs_refclk_out like Espresso (with one difference -
> ufs_rst_n shouldn't be pulled up).
> 
> About regulators (it would be easier if dts would have all regulators).
> It's also using s2mps15 as Espresso, but it vendor dts had only 8 (of
> 10 possible bucks, one missing was for UFS) and 14 ldos (of 27
> possible), where almost all rails are connected to something.
> 
> I'm wondering how it's working on Espresso, because when adding correct
> regulators for ufs (vccq = buck10 from s2mps15, always enabled for
> testing plus vccq2 and vccq = two regulators enabled by one gpio,
> enabled at boot by firmware), ufs wasn't still working because it was
> then failing at defer probe (s2mps15 was probed after ufs)
> 
> [    0.962482] exynos-ufshc 15570000.ufs: ufshcd_get_vreg: vccq get
> failed, err=-517
>
As I said, this is very specific to the board, on Espresso we have LDO12 connected to UFS_RESETn.
Either make all of them as always-on, or just disabled s2mps15 
(default voltage supply should be ok, unless bootloader on your board does have messed too much with PMIC)
 
> After that boot would just stop/hang.
> 
> After making a "dirty fix" by making s2mps15 regulator driver use
> subsys_initcall (like in vendor sources) and ufs late_initcall (to give
> it more time to setup and get it working and solve it later),
> i had to mark following clocks as CLK_IGNORE_UNUSED to be able to bring
> link up (it replicates setting done by vendor kernel, which enables
> them on boot):
> - "phyclk_ufs20_rx1_symbol_user"
> - "phyclk_ufs20_rx0_symbol_user"
> - "phyclk_ufs20_tx0_symbol_user"
> 
Coming to these clocks, all these are supplied by default, my best guess is since you are using an actual product (S6 edge), they might have optimized for power saving 
And most likely all clock might be  gated initially. In my case all are set to default.
I have attached a small change in the exynos7 dts and phy driver clock handling, please try this attached patch and let me know if this helps in removing some of your hacks.
In the later SoCs these clocks are not in this form, so I didn't included in my current patch set, If this works for your, will add as an optional for exynos7/7420.
I also assume you are using clk-exynos7.c and my posted ufs driver.

> Now it's able to bring both device and link, but it fails at
> ufshcd_uic_change_pwr_mode.
> 
Can you please use the exact ufs and ufs-phy device node as in my patch?

> [    1.411547] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> core_clk, rate: 100000000
> [    1.419698] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> sclk_unipro_main, rate: 167000000
> [    1.428550] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> core_clk enabled
> [    1.436200] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> sclk_unipro_main enabled
> [    1.445704] scsi host0: ufshcd
> [    1.465684] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate
> =
> 0
> [    2.023699] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> 0x1fff error code 1
> [    2.023846] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> 0x1fff failed 0 retries
> [    2.024025] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> 0xffff error code 1
> [    2.025457] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> 0xffff failed 0 retries
> [    2.033777] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> 0x7fff error code 1
> [    2.041607] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> 0x7fff failed 0 retries
> [    2.067809] exynos-ufshc 15570000.ufs: pwr ctrl cmd 0x2 failed, host
> upmcrs:0x5
> [    2.067953] exynos-ufshc 15570000.ufs: UFS Host state=0
> [    2.068056] exynos-ufshc 15570000.ufs: outstanding reqs=0x0
> tasks=0x0
> [    2.068759] exynos-ufshc 15570000.ufs: saved_err=0x0,
> saved_uic_err=0x0
> [    2.075368] exynos-ufshc 15570000.ufs: Device power mode=1, UIC link
> state=1
> [    2.082392] exynos-ufshc 15570000.ufs: PM in progress=0, sys.
> suspended=0
> [    2.089158] exynos-ufshc 15570000.ufs: Auto BKOPS=0, Host self-
> block=0
> [    2.095667] exynos-ufshc 15570000.ufs: Clk gate=1
> [    2.100354] exynos-ufshc 15570000.ufs: error handling flags=0x0,
> req. abort count=0
> [    2.107987] exynos-ufshc 15570000.ufs: Host capabilities=0x383ff0f,
> caps=0x0
> [    2.115018] exynos-ufshc 15570000.ufs: quirks=0x780, dev.
> quirks=0xc4
> [    2.121443] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate
> =
> 0
> [    2.133960] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
> [    2.140268] host_regs: 00000010: 00000101 00007fce 00000000 00000000
> [    2.146604] host_regs: 00000020: 00000000 00030a75 00000000 00000000
> [    2.152940] host_regs: 00000030: 0000050f 00000000 80000010 00000000
> [    2.159271] host_regs: 00000040: 00000000 00000000 00000000 00000000
> [    2.165609] host_regs: 00000050: f9587000 00000000 00000000 00000000
> [    2.171944] host_regs: 00000060: 00000001 00000000 00000000 00000000
> [    2.178278] host_regs: 00000070: f958a000 00000000 00000000 00000000
> [    2.184609] host_regs: 00000080: 00000001 00000000 00000000 00000000
> [    2.190945] host_regs: 00000090: 00000002 15710000 00000000 00000000
> [    2.197282] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
> hba->capabilities = 0x383ff0f
> [    2.205869] exynos-ufshc 15570000.ufs: hba->outstanding_reqs = 0x0,
> hba->outstanding_tasks = 0x0
> [    2.214636] exynos-ufshc 15570000.ufs: last_hibern8_exit_tstamp at 0
> us, hibern8_exit_cnt = 0
> [    2.223141] exynos-ufshc 15570000.ufs: No record of pa_err
> [    2.228606] exynos-ufshc 15570000.ufs: No record of dl_err
> [    2.234071] exynos-ufshc 15570000.ufs: No record of nl_err
> [    2.239540] exynos-ufshc 15570000.ufs: No record of tl_err
> [    2.245007] exynos-ufshc 15570000.ufs: No record of dme_err
> [    2.250558] exynos-ufshc 15570000.ufs: No record of auto_hibern8_err
> [    2.256895] exynos-ufshc 15570000.ufs: No record of fatal_err
> [    2.262624] exynos-ufshc 15570000.ufs: No record of
> link_startup_fail
> [    2.269044] exynos-ufshc 15570000.ufs: No record of resume_fail
> [    2.274942] exynos-ufshc 15570000.ufs: No record of suspend_fail
> [    2.280931] exynos-ufshc 15570000.ufs: No record of dev_reset
> [    2.286659] exynos-ufshc 15570000.ufs: No record of host_reset
> [    2.292475] exynos-ufshc 15570000.ufs: No record of task_abort
> [    2.298290] exynos-ufshc 15570000.ufs: ufshcd_change_power_mode:
> power mode change failed 5
> [    2.306619] exynos-ufshc 15570000.ufs: ufshcd_probe_hba: Failed
> setting power mode, err = 5
> [    2.315144] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> core_clk disabled
> 
> And here boot would just stop/hang.
> 
> Thanks for all hints.
> 
> >
> >
> > > > > Also looking at clk-exynos7 driver seems to confirm this.
> > > > >
> > > > > > +		};
> > > > > > +
> > > > > >  		usbdrd_phy: phy@15500000 {
> > > > > >  			compatible = "samsung,exynos7-usbdrd-phy";
> > > > > >  			reg = <0x15500000 0x100>;
> >
> >



[-- Attachment #2: ufs_phy_clk.patch --]
[-- Type: application/octet-stream, Size: 4939 bytes --]

diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index a9531c4bf22f..9a4dd9ae5cdf 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -665,9 +665,14 @@
 			reg-names = "phy-pma";
 			samsung,pmu-syscon = <&pmu_system_controller>;
 			#phy-cells = <0>;
-			clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
-				<&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
-			clock-names = "ref_clk_parent", "ref_clk";
+			clocks = <&clock_top1 DOUT_SCLK_PHY_FSYS1_26M>,
+				 <&clock_fsys1 SCLK_COMBO_PHY_EMBEDDED_26M>,
+				 <&clock_fsys1 PHYCLK_UFS20_RX1_SYMBOL_USER>,
+				 <&clock_fsys1 PHYCLK_UFS20_RX0_SYMBOL_USER>,
+				 <&clock_fsys1 PHYCLK_UFS20_TX0_SYMBOL_USER>;
+			clock-names = "ref_clk_parent", "ref_clk",
+					"rx1_symbol_clk", "rx0_symbol_clk",
+					"tx0_symbol_clk";
 		};
 
 		usbdrd_phy: phy@15500000 {
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
index 572e40e72776..2d5dcd670927 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.c
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -136,9 +136,63 @@ int samsung_ufs_phy_calibrate(struct phy *phy)
 	return err;
 }
 
+static int samsung_ufs_phy_symbol_clk_init(struct samsung_ufs_phy *phy)
+{
+	struct clk *clk;
+	int ret = 0;
+
+	clk = devm_clk_get(phy->dev, "tx0_symbol_clk");
+	if (IS_ERR(clk)) {
+		dev_err(phy->dev, "failed to get tx0_symbol_clk clock\n");
+		goto out;
+	} else {
+		phy->tx0_symbol_clk = clk;
+	}
+
+	clk = devm_clk_get(phy->dev, "rx0_symbol_clk");
+	if (IS_ERR(clk)) {
+		dev_err(phy->dev, "failed to get rx0_symbol_clk clock\n");
+		goto out;
+	} else {
+		phy->rx0_symbol_clk = clk;
+	}
+
+	clk = devm_clk_get(phy->dev, "rx1_symbol_clk");
+	if (IS_ERR(clk)) {
+		dev_err(phy->dev, "failed to get rx1_symbol_clk clock\n");
+		goto out;
+	} else {
+		phy->rx1_symbol_clk = clk;
+	}
+
+	ret = clk_prepare_enable(phy->tx0_symbol_clk);
+	if (ret) {
+		dev_err(phy->dev, "%s: tx0_symbol_clk enable failed %d\n",
+				__func__, ret);
+		goto out;
+	}
+	ret = clk_prepare_enable(phy->rx0_symbol_clk);
+	if (ret) {
+		dev_err(phy->dev, "%s: rx0_symbol_clk enable failed %d\n",
+				__func__, ret);
+		goto out;
+	}
+	ret = clk_prepare_enable(phy->rx1_symbol_clk);
+	if (ret) {
+		dev_err(phy->dev, "%s: rx1_symbol_clk enable failed %d\n",
+				__func__, ret);
+		goto out;
+	}
+out:
+	return ret;
+}
+
 static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy)
 {
 	struct clk *child, *parent;
+	u32 phy_clk_rate, phy_parent_rate;
+	int ret;
+
 
 	child = devm_clk_get(phy->dev, "ref_clk");
 	if (IS_ERR(child))
@@ -146,18 +200,32 @@ static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy)
 	else
 		phy->ref_clk = child;
 
+	ret = clk_prepare_enable(phy->ref_clk);
+	if (ret) {
+		dev_err(phy->dev, "%s: ref_clk enable failed %d\n",
+				__func__, ret);
+		return ret;
+	}
+
+	phy_clk_rate = clk_get_rate(child);
+	dev_info(phy->dev, "MPHY ref_clk_rate = %d\n", phy_clk_rate);
+
 	parent = devm_clk_get(phy->dev, "ref_clk_parent");
 	if (IS_ERR(parent))
 		dev_err(phy->dev, "failed to get ref_clk_parent clock\n");
 	else
 		phy->ref_clk_parent = parent;
 
+	phy_parent_rate = clk_get_rate(parent);
+	dev_info(phy->dev, "MPHY ref_parent_clk_rate = %d\n", phy_parent_rate);
+
 	return clk_set_parent(child, parent);
 }
 
 static int samsung_ufs_phy_init(struct phy *phy)
 {
 	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy);
+	int ret;
 
 	_phy->lane_cnt = phy->attrs.bus_width;
 	_phy->ufs_phy_state = CFG_PRE_INIT;
@@ -167,7 +235,13 @@ static int samsung_ufs_phy_init(struct phy *phy)
 	_phy->is_pre_pmc = false;
 	_phy->is_post_pmc = false;
 
-	samsung_ufs_phy_clks_init(_phy);
+	ret = samsung_ufs_phy_symbol_clk_init(_phy);
+	if (ret)
+		dev_err(_phy->dev, "failed to set ufs phy symbol clocks\n");
+
+	ret = samsung_ufs_phy_clks_init(_phy);
+	if (!ret)
+		dev_err(_phy->dev, "failed to set ufs phy  clocks\n");
 
 	samsung_ufs_phy_calibrate(phy);
 
@@ -177,14 +251,6 @@ static int samsung_ufs_phy_init(struct phy *phy)
 static int samsung_ufs_phy_power_on(struct phy *phy)
 {
 	struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy);
-	int ret;
-
-	ret = clk_prepare_enable(_phy->ref_clk);
-	if (ret) {
-		dev_err(_phy->dev, "%s: ref_clk enable failed %d\n",
-				__func__, ret);
-		return ret;
-	}
 
 	samsung_ufs_phy_ctrl_isol(_phy, false);
 	return 0;
diff --git a/drivers/phy/samsung/phy-samsung-ufs.h b/drivers/phy/samsung/phy-samsung-ufs.h
index 971d67ae7f80..27dc1b573469 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.h
+++ b/drivers/phy/samsung/phy-samsung-ufs.h
@@ -110,6 +110,9 @@ struct samsung_ufs_phy {
 	struct regmap *reg_pmu;
 	struct clk *ref_clk;
 	struct clk *ref_clk_parent;
+	struct clk *tx0_symbol_clk;
+	struct clk *rx0_symbol_clk;
+	struct clk *rx1_symbol_clk;
 	const struct samsung_ufs_phy_drvdata *drvdata;
 	struct samsung_ufs_phy_cfg **cfg;
 	const struct pmu_isol *isol;

[-- Attachment #3: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-04-04 18:15                 ` Alim Akhtar
@ 2020-04-04 19:33                   ` Paweł Chmiel
  2020-04-04 20:25                     ` Paweł Chmiel
  0 siblings, 1 reply; 22+ messages in thread
From: Paweł Chmiel @ 2020-04-04 19:33 UTC (permalink / raw)
  To: Alim Akhtar, robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

On Sat, 2020-04-04 at 23:45 +0530, Alim Akhtar wrote:
Hi Alim,
> Hi Pawel,
> 
> > -----Original Message-----
> > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > Sent: 03 April 2020 22:22
> > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> > kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> > cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > 
> > Hi Alim
> > 
> > Looking at vendor sources, my device is using the same gpios for
> > urfs_rst_n and ufs_refclk_out like Espresso (with one difference -
> > ufs_rst_n shouldn't be pulled up).
> > 
> > About regulators (it would be easier if dts would have all regulators).
> > It's also using s2mps15 as Espresso, but it vendor dts had only 8 (of
> > 10 possible bucks, one missing was for UFS) and 14 ldos (of 27
> > possible), where almost all rails are connected to something.
> > 
> > I'm wondering how it's working on Espresso, because when adding correct
> > regulators for ufs (vccq = buck10 from s2mps15, always enabled for
> > testing plus vccq2 and vccq = two regulators enabled by one gpio,
> > enabled at boot by firmware), ufs wasn't still working because it was
> > then failing at defer probe (s2mps15 was probed after ufs)
> > 
> > [    0.962482] exynos-ufshc 15570000.ufs: ufshcd_get_vreg: vccq get
> > failed, err=-517
> > 
> As I said, this is very specific to the board, on Espresso we have LDO12 connected to UFS_RESETn.
> Either make all of them as always-on, or just disabled s2mps15 
> (default voltage supply should be ok, unless bootloader on your board does have messed too much with PMIC)
>  
> > After that boot would just stop/hang.
> > 
> > After making a "dirty fix" by making s2mps15 regulator driver use
> > subsys_initcall (like in vendor sources) and ufs late_initcall (to give
> > it more time to setup and get it working and solve it later),
> > i had to mark following clocks as CLK_IGNORE_UNUSED to be able to bring
> > link up (it replicates setting done by vendor kernel, which enables
> > them on boot):
> > - "phyclk_ufs20_rx1_symbol_user"
> > - "phyclk_ufs20_rx0_symbol_user"
> > - "phyclk_ufs20_tx0_symbol_user"
> > 
> Coming to these clocks, all these are supplied by default, my best guess is since you are using an actual product (S6 edge), they might have optimized for power saving 
> And most likely all clock might be  gated initially. In my case all are set to default.
> I have attached a small change in the exynos7 dts and phy driver clock handling, please try this attached patch and let me know if this helps in removing some of your hacks.
> In the later SoCs these clocks are not in this form, so I didn't included in my current patch set, If this works for your, will add as an optional for exynos7/7420.
> I also assume you are using clk-exynos7.c and my posted ufs driver.
Yes, i'm using clk-exynos7 (and other exynos7 drivers/dts/etc).
It would be great if someone could say how exynos7 and exynos7420 are
similar. For now it looks like that only difference is that exynos7 has
only 4 cores (a57) where 7420 has 4xa53 + 4xa57.
It would be very valuable information for me so i could know how much i
could reuse my device.
> 
> > Now it's able to bring both device and link, but it fails at
> > ufshcd_uic_change_pwr_mode.
> > 
> Can you please use the exact ufs and ufs-phy device node as in my patch?
With Your patch + removed my changes to clocks (removed fix for wrong
clock order in dts + removed CLK_IGNORE_UNUSED from symbol clocks in
clk-exynos7) it's finally able to detect my UFS device!! 

(but of fails later...with constant error spam in kernel log).

[    1.383481] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: Unable
to find vdd-hba-supply regulator, assuming enabled
[    1.390060] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
to find vcc-max-microamp
[    1.398465] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
to find vccq-max-microamp
[    1.406968] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
to find vccq2-max-microamp
[    1.415569] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
core_clk, rate: 100000000
[    1.423715] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
sclk_unipro_main, rate: 167000000
[    1.432569] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
core_clk enabled
[    1.440205] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
sclk_unipro_main enabled
[    1.449613] scsi host0: ufshcd
[    1.452179] samsung-ufs-phy 15571800.ufs-phy: MPHY ref_clk_rate =
26000000
[    1.458448] samsung-ufs-phy 15571800.ufs-phy: MPHY
ref_parent_clk_rate = 26000000
[    1.487288] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate =
0
[    2.025569] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
0x1fff error code 1
[    2.025715] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
0x1fff failed 0 retries
[    2.025880] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
0xffff error code 1
[    2.027354] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
0xffff failed 0 retries
[    2.035583] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
0x7fff error code 1
[    2.043465] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
0x7fff failed 0 retries
[    2.054049] exynos-ufshc 15570000.ufs: Power mode change 0 : Fast
series_B G_2 L_2
[    2.059261] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
TX]: gear=[2, 2], lane[2, 2], pwr[FAST MODE, FAST MODE], rate = 2
[    2.071307] exynos-ufshc 15570000.ufs: ufshcd_init_icc_levels:
setting icc_level 0x0
[    2.081624] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
activate tcq with queue depth 1
[    2.087576] scsi 0:0:0:49488: scsi_add_lun: correcting incorrect
peripheral device type 0x0 for W-LUN 0x            c150hN
[    2.098400] scsi 0:0:0:49488: Well-known LUN    SAMSUNG  KLUBG4G1BD-
E0B1  0200 PQ: 0 ANSI: 6
[    2.107585] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
activate tcq with queue depth 16
[    2.115588] scsi 0:0:0:49476: scsi_add_lun: correcting incorrect
peripheral device type 0x0 for W-LUN 0x            c144hN
[    2.126519] scsi 0:0:0:49476: Well-known LUN    SAMSUNG  KLUBG4G1BD-
E0B1  0200 PQ: 0 ANSI: 6
[    2.135534] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
activate tcq with queue depth 1
[    2.143612] scsi 0:0:0:49456: scsi_add_lun: correcting incorrect
peripheral device type 0x0 for W-LUN 0x            c130hN
[    2.154543] scsi 0:0:0:49456: Well-known LUN    SAMSUNG  KLUBG4G1BD-
E0B1  0200 PQ: 0 ANSI: 6
[    2.163597] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
activate tcq with queue depth 16
[    2.171721] scsi 0:0:0:0: Direct-Access     SAMSUNG  KLUBG4G1BD-
E0B1  0200 PQ: 0 ANSI: 6
[    2.180352] exynos-ufshc 15570000.ufs: OCS error from controller = 7
for tag 0
[    2.186921] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
[    2.193230] host_regs: 00000010: 00000101 00007fce 00000c96 00000000
[    2.199565] host_regs: 00000020: 00000000 00030e75 00000000 00000000
[    2.205899] host_regs: 00000030: 0000010f 00000000 80000010 00000000
[    2.212234] host_regs: 00000040: 00000000 00000000 00000000 00000000
[    2.218568] host_regs: 00000050: f8d64000 00000000 00000000 00000000
[    2.224903] host_regs: 00000060: 00000001 00000000 00000000 00000000
[    2.231237] host_regs: 00000070: f8da2000 00000000 00000000 00000000
[    2.237572] host_regs: 00000080: 00000001 00000000 00000000 00000000
[    2.243907] host_regs: 00000090: 00000002 95190000 00000000 00000000
[    2.250242] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
hba->capabilities = 0x383ff0f

Full bootlog 
https://gist.github.com/PabloPL/0bcb24492f4ab6e9703c2a4ea20ceb18
kernel source: https://github.com/PabloPL/linux/tree/ufs-mainline
dts file: exynos7-zeroflt.dts (it should be zerolt, but will be
fixed/changed later).

Thanks
> 
> > [    1.411547] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > core_clk, rate: 100000000
> > [    1.419698] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > sclk_unipro_main, rate: 167000000
> > [    1.428550] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > core_clk enabled
> > [    1.436200] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > sclk_unipro_main enabled
> > [    1.445704] scsi host0: ufshcd
> > [    1.465684] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate
> > =
> > 0
> > [    2.023699] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > 0x1fff error code 1
> > [    2.023846] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > 0x1fff failed 0 retries
> > [    2.024025] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > 0xffff error code 1
> > [    2.025457] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > 0xffff failed 0 retries
> > [    2.033777] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > 0x7fff error code 1
> > [    2.041607] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > 0x7fff failed 0 retries
> > [    2.067809] exynos-ufshc 15570000.ufs: pwr ctrl cmd 0x2 failed, host
> > upmcrs:0x5
> > [    2.067953] exynos-ufshc 15570000.ufs: UFS Host state=0
> > [    2.068056] exynos-ufshc 15570000.ufs: outstanding reqs=0x0
> > tasks=0x0
> > [    2.068759] exynos-ufshc 15570000.ufs: saved_err=0x0,
> > saved_uic_err=0x0
> > [    2.075368] exynos-ufshc 15570000.ufs: Device power mode=1, UIC link
> > state=1
> > [    2.082392] exynos-ufshc 15570000.ufs: PM in progress=0, sys.
> > suspended=0
> > [    2.089158] exynos-ufshc 15570000.ufs: Auto BKOPS=0, Host self-
> > block=0
> > [    2.095667] exynos-ufshc 15570000.ufs: Clk gate=1
> > [    2.100354] exynos-ufshc 15570000.ufs: error handling flags=0x0,
> > req. abort count=0
> > [    2.107987] exynos-ufshc 15570000.ufs: Host capabilities=0x383ff0f,
> > caps=0x0
> > [    2.115018] exynos-ufshc 15570000.ufs: quirks=0x780, dev.
> > quirks=0xc4
> > [    2.121443] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate
> > =
> > 0
> > [    2.133960] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
> > [    2.140268] host_regs: 00000010: 00000101 00007fce 00000000 00000000
> > [    2.146604] host_regs: 00000020: 00000000 00030a75 00000000 00000000
> > [    2.152940] host_regs: 00000030: 0000050f 00000000 80000010 00000000
> > [    2.159271] host_regs: 00000040: 00000000 00000000 00000000 00000000
> > [    2.165609] host_regs: 00000050: f9587000 00000000 00000000 00000000
> > [    2.171944] host_regs: 00000060: 00000001 00000000 00000000 00000000
> > [    2.178278] host_regs: 00000070: f958a000 00000000 00000000 00000000
> > [    2.184609] host_regs: 00000080: 00000001 00000000 00000000 00000000
> > [    2.190945] host_regs: 00000090: 00000002 15710000 00000000 00000000
> > [    2.197282] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
> > hba->capabilities = 0x383ff0f
> > [    2.205869] exynos-ufshc 15570000.ufs: hba->outstanding_reqs = 0x0,
> > hba->outstanding_tasks = 0x0
> > [    2.214636] exynos-ufshc 15570000.ufs: last_hibern8_exit_tstamp at 0
> > us, hibern8_exit_cnt = 0
> > [    2.223141] exynos-ufshc 15570000.ufs: No record of pa_err
> > [    2.228606] exynos-ufshc 15570000.ufs: No record of dl_err
> > [    2.234071] exynos-ufshc 15570000.ufs: No record of nl_err
> > [    2.239540] exynos-ufshc 15570000.ufs: No record of tl_err
> > [    2.245007] exynos-ufshc 15570000.ufs: No record of dme_err
> > [    2.250558] exynos-ufshc 15570000.ufs: No record of auto_hibern8_err
> > [    2.256895] exynos-ufshc 15570000.ufs: No record of fatal_err
> > [    2.262624] exynos-ufshc 15570000.ufs: No record of
> > link_startup_fail
> > [    2.269044] exynos-ufshc 15570000.ufs: No record of resume_fail
> > [    2.274942] exynos-ufshc 15570000.ufs: No record of suspend_fail
> > [    2.280931] exynos-ufshc 15570000.ufs: No record of dev_reset
> > [    2.286659] exynos-ufshc 15570000.ufs: No record of host_reset
> > [    2.292475] exynos-ufshc 15570000.ufs: No record of task_abort
> > [    2.298290] exynos-ufshc 15570000.ufs: ufshcd_change_power_mode:
> > power mode change failed 5
> > [    2.306619] exynos-ufshc 15570000.ufs: ufshcd_probe_hba: Failed
> > setting power mode, err = 5
> > [    2.315144] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > core_clk disabled
> > 
> > And here boot would just stop/hang.
> > 
> > Thanks for all hints.
> > 
> > > 
> > > > > > Also looking at clk-exynos7 driver seems to confirm this.
> > > > > > 
> > > > > > > +		};
> > > > > > > +
> > > > > > >  		usbdrd_phy: phy@15500000 {
> > > > > > >  			compatible = "samsung,exynos7-usbdrd-phy";
> > > > > > >  			reg = <0x15500000 0x100>;
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-04-04 19:33                   ` Paweł Chmiel
@ 2020-04-04 20:25                     ` Paweł Chmiel
  2020-04-05  1:48                       ` Alim Akhtar
  0 siblings, 1 reply; 22+ messages in thread
From: Paweł Chmiel @ 2020-04-04 20:25 UTC (permalink / raw)
  To: Alim Akhtar, robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

On Sat, 2020-04-04 at 21:33 +0200, Paweł Chmiel wrote:
> On Sat, 2020-04-04 at 23:45 +0530, Alim Akhtar wrote:
> Hi Alim,
> > Hi Pawel,
> > 
> > > -----Original Message-----
> > > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > > Sent: 03 April 2020 22:22
> > > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > > Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> > > kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> > > cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> > > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > > 
> > > Hi Alim
> > > 
> > > Looking at vendor sources, my device is using the same gpios for
> > > urfs_rst_n and ufs_refclk_out like Espresso (with one difference -
> > > ufs_rst_n shouldn't be pulled up).
> > > 
> > > About regulators (it would be easier if dts would have all regulators).
> > > It's also using s2mps15 as Espresso, but it vendor dts had only 8 (of
> > > 10 possible bucks, one missing was for UFS) and 14 ldos (of 27
> > > possible), where almost all rails are connected to something.
> > > 
> > > I'm wondering how it's working on Espresso, because when adding correct
> > > regulators for ufs (vccq = buck10 from s2mps15, always enabled for
> > > testing plus vccq2 and vccq = two regulators enabled by one gpio,
> > > enabled at boot by firmware), ufs wasn't still working because it was
> > > then failing at defer probe (s2mps15 was probed after ufs)
> > > 
> > > [    0.962482] exynos-ufshc 15570000.ufs: ufshcd_get_vreg: vccq get
> > > failed, err=-517
> > > 
> > As I said, this is very specific to the board, on Espresso we have LDO12 connected to UFS_RESETn.
> > Either make all of them as always-on, or just disabled s2mps15 
> > (default voltage supply should be ok, unless bootloader on your board does have messed too much with PMIC)
> >  
> > > After that boot would just stop/hang.
> > > 
> > > After making a "dirty fix" by making s2mps15 regulator driver use
> > > subsys_initcall (like in vendor sources) and ufs late_initcall (to give
> > > it more time to setup and get it working and solve it later),
> > > i had to mark following clocks as CLK_IGNORE_UNUSED to be able to bring
> > > link up (it replicates setting done by vendor kernel, which enables
> > > them on boot):
> > > - "phyclk_ufs20_rx1_symbol_user"
> > > - "phyclk_ufs20_rx0_symbol_user"
> > > - "phyclk_ufs20_tx0_symbol_user"
> > > 
> > Coming to these clocks, all these are supplied by default, my best guess is since you are using an actual product (S6 edge), they might have optimized for power saving 
> > And most likely all clock might be  gated initially. In my case all are set to default.
> > I have attached a small change in the exynos7 dts and phy driver clock handling, please try this attached patch and let me know if this helps in removing some of your hacks.
> > In the later SoCs these clocks are not in this form, so I didn't included in my current patch set, If this works for your, will add as an optional for exynos7/7420.
> > I also assume you are using clk-exynos7.c and my posted ufs driver.
> Yes, i'm using clk-exynos7 (and other exynos7 drivers/dts/etc).
> It would be great if someone could say how exynos7 and exynos7420 are
> similar. For now it looks like that only difference is that exynos7 has
> only 4 cores (a57) where 7420 has 4xa53 + 4xa57.
> It would be very valuable information for me so i could know how much i
> could reuse my device.
> > > Now it's able to bring both device and link, but it fails at
> > > ufshcd_uic_change_pwr_mode.
> > > 
> > Can you please use the exact ufs and ufs-phy device node as in my patch?
> With Your patch + removed my changes to clocks (removed fix for wrong
> clock order in dts + removed CLK_IGNORE_UNUSED from symbol clocks in
> clk-exynos7) it's finally able to detect my UFS device!! 
> 
> (but of fails later...with constant error spam in kernel log).
> 
> [    1.383481] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: Unable
> to find vdd-hba-supply regulator, assuming enabled
> [    1.390060] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> to find vcc-max-microamp
> [    1.398465] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> to find vccq-max-microamp
> [    1.406968] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> to find vccq2-max-microamp
> [    1.415569] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> core_clk, rate: 100000000
> [    1.423715] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> sclk_unipro_main, rate: 167000000
> [    1.432569] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> core_clk enabled
> [    1.440205] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> sclk_unipro_main enabled
> [    1.449613] scsi host0: ufshcd
> [    1.452179] samsung-ufs-phy 15571800.ufs-phy: MPHY ref_clk_rate =
> 26000000
> [    1.458448] samsung-ufs-phy 15571800.ufs-phy: MPHY
> ref_parent_clk_rate = 26000000
> [    1.487288] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate =
> 0
> [    2.025569] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> 0x1fff error code 1
> [    2.025715] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> 0x1fff failed 0 retries
> [    2.025880] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> 0xffff error code 1
> [    2.027354] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> 0xffff failed 0 retries
> [    2.035583] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> 0x7fff error code 1
> [    2.043465] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> 0x7fff failed 0 retries
> [    2.054049] exynos-ufshc 15570000.ufs: Power mode change 0 : Fast
> series_B G_2 L_2
> [    2.059261] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> TX]: gear=[2, 2], lane[2, 2], pwr[FAST MODE, FAST MODE], rate = 2
> [    2.071307] exynos-ufshc 15570000.ufs: ufshcd_init_icc_levels:
> setting icc_level 0x0
> [    2.081624] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> activate tcq with queue depth 1
> [    2.087576] scsi 0:0:0:49488: scsi_add_lun: correcting incorrect
> peripheral device type 0x0 for W-LUN 0x            c150hN
> [    2.098400] scsi 0:0:0:49488: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> E0B1  0200 PQ: 0 ANSI: 6
> [    2.107585] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> activate tcq with queue depth 16
> [    2.115588] scsi 0:0:0:49476: scsi_add_lun: correcting incorrect
> peripheral device type 0x0 for W-LUN 0x            c144hN
> [    2.126519] scsi 0:0:0:49476: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> E0B1  0200 PQ: 0 ANSI: 6
> [    2.135534] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> activate tcq with queue depth 1
> [    2.143612] scsi 0:0:0:49456: scsi_add_lun: correcting incorrect
> peripheral device type 0x0 for W-LUN 0x            c130hN
> [    2.154543] scsi 0:0:0:49456: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> E0B1  0200 PQ: 0 ANSI: 6
> [    2.163597] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> activate tcq with queue depth 16
> [    2.171721] scsi 0:0:0:0: Direct-Access     SAMSUNG  KLUBG4G1BD-
> E0B1  0200 PQ: 0 ANSI: 6
> [    2.180352] exynos-ufshc 15570000.ufs: OCS error from controller = 7
> for tag 0
> [    2.186921] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
> [    2.193230] host_regs: 00000010: 00000101 00007fce 00000c96 00000000
> [    2.199565] host_regs: 00000020: 00000000 00030e75 00000000 00000000
> [    2.205899] host_regs: 00000030: 0000010f 00000000 80000010 00000000
> [    2.212234] host_regs: 00000040: 00000000 00000000 00000000 00000000
> [    2.218568] host_regs: 00000050: f8d64000 00000000 00000000 00000000
> [    2.224903] host_regs: 00000060: 00000001 00000000 00000000 00000000
> [    2.231237] host_regs: 00000070: f8da2000 00000000 00000000 00000000
> [    2.237572] host_regs: 00000080: 00000001 00000000 00000000 00000000
> [    2.243907] host_regs: 00000090: 00000002 95190000 00000000 00000000
> [    2.250242] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
> hba->capabilities = 0x383ff0f
> 
> Full bootlog 
> https://gist.github.com/PabloPL/0bcb24492f4ab6e9703c2a4ea20ceb18
> kernel source: https://github.com/PabloPL/linux/tree/ufs-mainline
> dts file: exynos7-zeroflt.dts (it should be zerolt, but will be
> fixed/changed later).

Actually, after waiting enough time (about 15 or even more sec of that
error "spam"), was able to mount partitions and manipulate files there.

So for me the only issue to solve are defered probe when regulators are
not yet found (for example when pmic is probed after ufs) and not sure
what about that errors (despite working ufs).

Thanks for all
> 
> Thanks
> > > [    1.411547] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > > core_clk, rate: 100000000
> > > [    1.419698] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > > sclk_unipro_main, rate: 167000000
> > > [    1.428550] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > > core_clk enabled
> > > [    1.436200] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > > sclk_unipro_main enabled
> > > [    1.445704] scsi host0: ufshcd
> > > [    1.465684] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > > TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate
> > > =
> > > 0
> > > [    2.023699] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > > 0x1fff error code 1
> > > [    2.023846] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > > 0x1fff failed 0 retries
> > > [    2.024025] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > > 0xffff error code 1
> > > [    2.025457] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > > 0xffff failed 0 retries
> > > [    2.033777] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > > 0x7fff error code 1
> > > [    2.041607] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > > 0x7fff failed 0 retries
> > > [    2.067809] exynos-ufshc 15570000.ufs: pwr ctrl cmd 0x2 failed, host
> > > upmcrs:0x5
> > > [    2.067953] exynos-ufshc 15570000.ufs: UFS Host state=0
> > > [    2.068056] exynos-ufshc 15570000.ufs: outstanding reqs=0x0
> > > tasks=0x0
> > > [    2.068759] exynos-ufshc 15570000.ufs: saved_err=0x0,
> > > saved_uic_err=0x0
> > > [    2.075368] exynos-ufshc 15570000.ufs: Device power mode=1, UIC link
> > > state=1
> > > [    2.082392] exynos-ufshc 15570000.ufs: PM in progress=0, sys.
> > > suspended=0
> > > [    2.089158] exynos-ufshc 15570000.ufs: Auto BKOPS=0, Host self-
> > > block=0
> > > [    2.095667] exynos-ufshc 15570000.ufs: Clk gate=1
> > > [    2.100354] exynos-ufshc 15570000.ufs: error handling flags=0x0,
> > > req. abort count=0
> > > [    2.107987] exynos-ufshc 15570000.ufs: Host capabilities=0x383ff0f,
> > > caps=0x0
> > > [    2.115018] exynos-ufshc 15570000.ufs: quirks=0x780, dev.
> > > quirks=0xc4
> > > [    2.121443] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > > TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE], rate
> > > =
> > > 0
> > > [    2.133960] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
> > > [    2.140268] host_regs: 00000010: 00000101 00007fce 00000000 00000000
> > > [    2.146604] host_regs: 00000020: 00000000 00030a75 00000000 00000000
> > > [    2.152940] host_regs: 00000030: 0000050f 00000000 80000010 00000000
> > > [    2.159271] host_regs: 00000040: 00000000 00000000 00000000 00000000
> > > [    2.165609] host_regs: 00000050: f9587000 00000000 00000000 00000000
> > > [    2.171944] host_regs: 00000060: 00000001 00000000 00000000 00000000
> > > [    2.178278] host_regs: 00000070: f958a000 00000000 00000000 00000000
> > > [    2.184609] host_regs: 00000080: 00000001 00000000 00000000 00000000
> > > [    2.190945] host_regs: 00000090: 00000002 15710000 00000000 00000000
> > > [    2.197282] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
> > > hba->capabilities = 0x383ff0f
> > > [    2.205869] exynos-ufshc 15570000.ufs: hba->outstanding_reqs = 0x0,
> > > hba->outstanding_tasks = 0x0
> > > [    2.214636] exynos-ufshc 15570000.ufs: last_hibern8_exit_tstamp at 0
> > > us, hibern8_exit_cnt = 0
> > > [    2.223141] exynos-ufshc 15570000.ufs: No record of pa_err
> > > [    2.228606] exynos-ufshc 15570000.ufs: No record of dl_err
> > > [    2.234071] exynos-ufshc 15570000.ufs: No record of nl_err
> > > [    2.239540] exynos-ufshc 15570000.ufs: No record of tl_err
> > > [    2.245007] exynos-ufshc 15570000.ufs: No record of dme_err
> > > [    2.250558] exynos-ufshc 15570000.ufs: No record of auto_hibern8_err
> > > [    2.256895] exynos-ufshc 15570000.ufs: No record of fatal_err
> > > [    2.262624] exynos-ufshc 15570000.ufs: No record of
> > > link_startup_fail
> > > [    2.269044] exynos-ufshc 15570000.ufs: No record of resume_fail
> > > [    2.274942] exynos-ufshc 15570000.ufs: No record of suspend_fail
> > > [    2.280931] exynos-ufshc 15570000.ufs: No record of dev_reset
> > > [    2.286659] exynos-ufshc 15570000.ufs: No record of host_reset
> > > [    2.292475] exynos-ufshc 15570000.ufs: No record of task_abort
> > > [    2.298290] exynos-ufshc 15570000.ufs: ufshcd_change_power_mode:
> > > power mode change failed 5
> > > [    2.306619] exynos-ufshc 15570000.ufs: ufshcd_probe_hba: Failed
> > > setting power mode, err = 5
> > > [    2.315144] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > > core_clk disabled
> > > 
> > > And here boot would just stop/hang.
> > > 
> > > Thanks for all hints.
> > > 
> > > > > > > Also looking at clk-exynos7 driver seems to confirm this.
> > > > > > > 
> > > > > > > > +		};
> > > > > > > > +
> > > > > > > >  		usbdrd_phy: phy@15500000 {
> > > > > > > >  			compatible = "samsung,exynos7-usbdrd-phy";
> > > > > > > >  			reg = <0x15500000 0x100>;


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-04-04 20:25                     ` Paweł Chmiel
@ 2020-04-05  1:48                       ` Alim Akhtar
  2020-04-05  8:11                         ` Paweł Chmiel
  0 siblings, 1 reply; 22+ messages in thread
From: Alim Akhtar @ 2020-04-05  1:48 UTC (permalink / raw)
  To: 'Paweł Chmiel', robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

Hi Pawel,

> -----Original Message-----
> From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> Sent: 05 April 2020 01:56
> To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> 
> On Sat, 2020-04-04 at 21:33 +0200, Paweł Chmiel wrote:
> > On Sat, 2020-04-04 at 23:45 +0530, Alim Akhtar wrote:
> > Hi Alim,
> > > Hi Pawel,
> > >
> > > > -----Original Message-----
> > > > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > > > Sent: 03 April 2020 22:22
> > > > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > > > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > > > Cc: krzk@kernel.org; avri.altman@wdc.com;
> > > > martin.petersen@oracle.com; kwmad.kim@samsung.com;
> > > > stanley.chu@mediatek.com; cang@codeaurora.org;
> > > > linux-samsung-soc@vger.kernel.org; linux-arm-
> > > > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > > > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > > >
> > > > Hi Alim
> > > >
> > > > Looking at vendor sources, my device is using the same gpios for
> > > > urfs_rst_n and ufs_refclk_out like Espresso (with one difference -
> > > > ufs_rst_n shouldn't be pulled up).
> > > >
> > > > About regulators (it would be easier if dts would have all regulators).
> > > > It's also using s2mps15 as Espresso, but it vendor dts had only 8
> > > > (of
> > > > 10 possible bucks, one missing was for UFS) and 14 ldos (of 27
> > > > possible), where almost all rails are connected to something.
> > > >
> > > > I'm wondering how it's working on Espresso, because when adding
> > > > correct regulators for ufs (vccq = buck10 from s2mps15, always
> > > > enabled for testing plus vccq2 and vccq = two regulators enabled
> > > > by one gpio, enabled at boot by firmware), ufs wasn't still
> > > > working because it was then failing at defer probe (s2mps15 was
> > > > probed after ufs)
> > > >
> > > > [    0.962482] exynos-ufshc 15570000.ufs: ufshcd_get_vreg: vccq get
> > > > failed, err=-517
> > > >
> > > As I said, this is very specific to the board, on Espresso we have LDO12
> connected to UFS_RESETn.
> > > Either make all of them as always-on, or just disabled s2mps15
> > > (default voltage supply should be ok, unless bootloader on your
> > > board does have messed too much with PMIC)
> > >
> > > > After that boot would just stop/hang.
> > > >
> > > > After making a "dirty fix" by making s2mps15 regulator driver use
> > > > subsys_initcall (like in vendor sources) and ufs late_initcall (to
> > > > give it more time to setup and get it working and solve it later),
> > > > i had to mark following clocks as CLK_IGNORE_UNUSED to be able to
> > > > bring link up (it replicates setting done by vendor kernel, which
> > > > enables them on boot):
> > > > - "phyclk_ufs20_rx1_symbol_user"
> > > > - "phyclk_ufs20_rx0_symbol_user"
> > > > - "phyclk_ufs20_tx0_symbol_user"
> > > >
> > > Coming to these clocks, all these are supplied by default, my best
> > > guess is since you are using an actual product (S6 edge), they might have
> optimized for power saving And most likely all clock might be  gated initially. In
> my case all are set to default.
> > > I have attached a small change in the exynos7 dts and phy driver clock
> handling, please try this attached patch and let me know if this helps in removing
> some of your hacks.
> > > In the later SoCs these clocks are not in this form, so I didn't included in my
> current patch set, If this works for your, will add as an optional for
> exynos7/7420.
> > > I also assume you are using clk-exynos7.c and my posted ufs driver.
> > Yes, i'm using clk-exynos7 (and other exynos7 drivers/dts/etc).
> > It would be great if someone could say how exynos7 and exynos7420 are
> > similar. For now it looks like that only difference is that exynos7
> > has only 4 cores (a57) where 7420 has 4xa53 + 4xa57.
> > It would be very valuable information for me so i could know how much
> > i could reuse my device.
> > > > Now it's able to bring both device and link, but it fails at
> > > > ufshcd_uic_change_pwr_mode.
> > > >
> > > Can you please use the exact ufs and ufs-phy device node as in my patch?
> > With Your patch + removed my changes to clocks (removed fix for wrong
> > clock order in dts + removed CLK_IGNORE_UNUSED from symbol clocks in
> > clk-exynos7) it's finally able to detect my UFS device!!
> >

Wow, great to know that UFS device started working for you on S6.

> > (but of fails later...with constant error spam in kernel log).
> >
> > [    1.383481] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: Unable
> > to find vdd-hba-supply regulator, assuming enabled
> > [    1.390060] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> > to find vcc-max-microamp
> > [    1.398465] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> > to find vccq-max-microamp
> > [    1.406968] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> > to find vccq2-max-microamp
> > [    1.415569] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > core_clk, rate: 100000000
> > [    1.423715] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > sclk_unipro_main, rate: 167000000
> > [    1.432569] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > core_clk enabled
> > [    1.440205] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > sclk_unipro_main enabled
> > [    1.449613] scsi host0: ufshcd
> > [    1.452179] samsung-ufs-phy 15571800.ufs-phy: MPHY ref_clk_rate =
> > 26000000
> > [    1.458448] samsung-ufs-phy 15571800.ufs-phy: MPHY
> > ref_parent_clk_rate = 26000000
> > [    1.487288] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE],
> rate
> > =
> > 0
> > [    2.025569] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > 0x1fff error code 1
> > [    2.025715] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > 0x1fff failed 0 retries
> > [    2.025880] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > 0xffff error code 1
> > [    2.027354] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > 0xffff failed 0 retries
> > [    2.035583] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > 0x7fff error code 1
> > [    2.043465] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > 0x7fff failed 0 retries
> > [    2.054049] exynos-ufshc 15570000.ufs: Power mode change 0 : Fast
> > series_B G_2 L_2
> > [    2.059261] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > TX]: gear=[2, 2], lane[2, 2], pwr[FAST MODE, FAST MODE], rate = 2
> > [    2.071307] exynos-ufshc 15570000.ufs: ufshcd_init_icc_levels:
> > setting icc_level 0x0
> > [    2.081624] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > activate tcq with queue depth 1
> > [    2.087576] scsi 0:0:0:49488: scsi_add_lun: correcting incorrect
> > peripheral device type 0x0 for W-LUN 0x            c150hN
> > [    2.098400] scsi 0:0:0:49488: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> > E0B1  0200 PQ: 0 ANSI: 6
> > [    2.107585] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > activate tcq with queue depth 16
> > [    2.115588] scsi 0:0:0:49476: scsi_add_lun: correcting incorrect
> > peripheral device type 0x0 for W-LUN 0x            c144hN
> > [    2.126519] scsi 0:0:0:49476: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> > E0B1  0200 PQ: 0 ANSI: 6
> > [    2.135534] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > activate tcq with queue depth 1
> > [    2.143612] scsi 0:0:0:49456: scsi_add_lun: correcting incorrect
> > peripheral device type 0x0 for W-LUN 0x            c130hN
> > [    2.154543] scsi 0:0:0:49456: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> > E0B1  0200 PQ: 0 ANSI: 6
> > [    2.163597] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > activate tcq with queue depth 16
> > [    2.171721] scsi 0:0:0:0: Direct-Access     SAMSUNG  KLUBG4G1BD-
> > E0B1  0200 PQ: 0 ANSI: 6
> > [    2.180352] exynos-ufshc 15570000.ufs: OCS error from controller = 7
> > for tag 0
> > [    2.186921] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
> > [    2.193230] host_regs: 00000010: 00000101 00007fce 00000c96 00000000
> > [    2.199565] host_regs: 00000020: 00000000 00030e75 00000000 00000000
> > [    2.205899] host_regs: 00000030: 0000010f 00000000 80000010 00000000
> > [    2.212234] host_regs: 00000040: 00000000 00000000 00000000 00000000
> > [    2.218568] host_regs: 00000050: f8d64000 00000000 00000000 00000000
> > [    2.224903] host_regs: 00000060: 00000001 00000000 00000000 00000000
> > [    2.231237] host_regs: 00000070: f8da2000 00000000 00000000 00000000
> > [    2.237572] host_regs: 00000080: 00000001 00000000 00000000 00000000
> > [    2.243907] host_regs: 00000090: 00000002 95190000 00000000 00000000
> > [    2.250242] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
> > hba->capabilities = 0x383ff0f
> >
> > Full bootlog
> > https://protect2.fireeye.com/url?k=edbae146-b069b8f8-edbb6a09-0cc47a31
> > ba82-
> 8b13b1e4caed34d7&q=1&u=https%3A%2F%2Fgist.github.com%2FPabloPL%2F
> > 0bcb24492f4ab6e9703c2a4ea20ceb18 kernel source:
> > https://protect2.fireeye.com/url?k=75038dec-28d0d452-750206a3-0cc47a31
> > ba82-
> 4c366bec6fc01e64&q=1&u=https%3A%2F%2Fgithub.com%2FPabloPL%2Flinux
> > %2Ftree%2Fufs-mainline dts file: exynos7-zeroflt.dts (it should be
> > zerolt, but will be fixed/changed later).
> 
> Actually, after waiting enough time (about 15 or even more sec of that error
> "spam"), was able to mount partitions and manipulate files there.
> 
You need below patch and  a change in the ufs driver:
https://www.spinics.net/lists/linux-scsi/msg138501.html

And

diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
index ce2c3d674e4b..c6332deff03a 100644
--- a/drivers/scsi/ufs/ufs-exynos.c
+++ b/drivers/scsi/ufs/ufs-exynos.c
@@ -1359,7 +1359,8 @@ struct exynos_ufs_drv_data exynos_ufs_drvs = {
        .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
                                  UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
                                  UFSHCI_QUIRK_BROKEN_HCE |
-                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR,
+                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
+                                 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR,
        .opts                   = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL |
                                  EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
                                  EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,

> So for me the only issue to solve are defered probe when regulators are not yet
> found (for example when pmic is probed after ufs) and not sure what about that
> errors (despite working ufs).
> 
The error will go away with the above changes, about regulators, you need to figure it out, as I am not aware of Galaxy S6 PMIC schemes.
I also seek your Tested-by tag on these patches .

> Thanks for all

Thanks for helping in testing.
> >
> > Thanks




_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 1/5] dt-bindings: phy: Document Samsung UFS PHY bindings
  2020-03-27 17:06     ` [PATCH v4 1/5] dt-bindings: phy: Document Samsung UFS PHY bindings Alim Akhtar
@ 2020-04-05  1:54       ` Rob Herring
  2020-04-07  0:28         ` Alim Akhtar
  0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2020-04-05  1:54 UTC (permalink / raw)
  To: Alim Akhtar
  Cc: devicetree, linux-samsung-soc, linux-scsi, martin.petersen,
	linux-kernel, krzk, kwmad.kim, avri.altman, cang, stanley.chu,
	linux-arm-kernel

On Fri, Mar 27, 2020 at 10:36:34PM +0530, Alim Akhtar wrote:
> This patch documents Samsung UFS PHY device tree bindings
> 
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> ---
>  .../bindings/phy/samsung,ufs-phy.yaml         | 67 +++++++++++++++++++
>  1 file changed, 67 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
> new file mode 100644
> index 000000000000..41ba481ecc76
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
> @@ -0,0 +1,67 @@
> +# SPDX-License-Identifier: (GPL-2.0)

Dual license new bindings:

(GPL-2.0-only OR BSD-2-Clause)

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/samsung,ufs-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung SoC series UFS PHY Device Tree Bindings
> +
> +maintainers:
> +  - Alim Akhtar <alim.akhtar@samsung.com>
> +
> +properties:
> +  "#phy-cells":
> +    const: 0
> +
> +  compatible:
> +    enum:
> +      - samsung,exynos7-ufs-phy
> +
> +  reg:
> +    maxItems: 1
> +    description: PHY base register address
> +
> +  reg-names:
> +    items:
> +      - const: phy-pma
> +
> +  clocks:
> +    items:
> +      - description: PLL reference clock
> +      - description: Referencec clock parrent
> +
> +  clock-names:
> +    items:
> +      - const: ref_clk_parent
> +      - const: ref_clk

Doesn't match what 'clocks' says.

Also, why do you need the parent in DT? Just use clk_get_parent(). DT 
should reflect actual h/w clock connections (not what the driver 
happens to need). Also, there's the assigned-clocks binding.

> +
> +  samsung,pmu-syscon:
> +    $ref: '/schemas/types.yaml#/definitions/phandle'
> +    description: phandle for PMU system controller interface, used to
> +                 control pmu registers for power isolation

We have a binding for power domains. Use that for power isolation.

> +
> +required:
> +  - "#phy-cells"
> +  - compatible
> +  - reg
> +  - reg-names
> +  - clocks
> +  - clock-names
> +  - samsung,pmu-syscon
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos7-clk.h>
> +
> +    ufs_phy: ufs-phy@15571800 {
> +        compatible = "samsung,exynos7-ufs-phy";
> +        reg = <0x15571800 0x240>;
> +        reg-names = "phy-pma";
> +        samsung,pmu-syscon = <&pmu_system_controller>;
> +        #phy-cells = <0>;
> +        clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
> +                 <&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
> +        clock-names = "ref_clk_parent",
> +                      "ref_clk";
> +    };
> +...
> 
> base-commit: fb33c6510d5595144d585aa194d377cf74d31911
> -- 
> 2.17.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 3/5] Documentation: devicetree: ufs: Add DT bindings for exynos UFS host controller
  2020-03-27 17:06     ` [PATCH v4 3/5] Documentation: devicetree: ufs: Add DT bindings for exynos UFS host controller Alim Akhtar
@ 2020-04-05  2:02       ` Rob Herring
  2020-04-12  5:41         ` Alim Akhtar
  0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2020-04-05  2:02 UTC (permalink / raw)
  To: Alim Akhtar
  Cc: devicetree, linux-samsung-soc, linux-scsi, martin.petersen,
	linux-kernel, krzk, kwmad.kim, avri.altman, cang, stanley.chu,
	linux-arm-kernel

On Fri, Mar 27, 2020 at 10:36:36PM +0530, Alim Akhtar wrote:
> This adds Exynos Universal Flash Storage (UFS) Host Controller DT bindings.

Why the inconsistent subject. 'dt-bindings: ...' please.

> 
> Signed-off-by: Seungwon Jeon <essuuj@gmail.com>
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> ---
>  .../devicetree/bindings/ufs/ufs-exynos.txt    | 104 ++++++++++++++++++
>  1 file changed, 104 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/ufs/ufs-exynos.txt

Use DT schema format. Not sure why you'd do that for one and not the 
other...

> 
> diff --git a/Documentation/devicetree/bindings/ufs/ufs-exynos.txt b/Documentation/devicetree/bindings/ufs/ufs-exynos.txt
> new file mode 100644
> index 000000000000..08e2d1497b1b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ufs/ufs-exynos.txt
> @@ -0,0 +1,104 @@
> +* Exynos Universal Flash Storage (UFS) Host Controller
> +
> +UFSHC nodes are defined to describe on-chip UFS host controllers.
> +Each UFS controller instance should have its own node.
> +
> +Required properties:
> +- compatible        : compatible name, contains "samsung,exynos7-ufs"
> +- interrupts        : <interrupt mapping for UFS host controller IRQ>
> +- reg               : Should contain HCI, vendor specific, UNIPRO and
> +		      UFS protector address space
> +- reg-names	    : "hci", "vs_hci", "unipro", "ufsp";
> +
> +Optional properties:
> +- vdd-hba-supply        : phandle to UFS host controller supply regulator node
> +- vcc-supply            : phandle to VCC supply regulator node
> +- vccq-supply           : phandle to VCCQ supply regulator node
> +- vccq2-supply          : phandle to VCCQ2 supply regulator node
> +- vcc-supply-1p8        : For embedded UFS devices, valid VCC range is 1.7-1.95V
> +                          or 2.7-3.6V. This boolean property when set, specifies
> +			  to use low voltage range of 1.7-1.95V. Note for external
> +			  UFS cards this property is invalid and valid VCC range is
> +			  always 2.7-3.6V.

The supply for vcc-supply should be restricted to the valid range and 
this is not needed.

> +- vcc-max-microamp      : specifies max. load that can be drawn from vcc supply
> +- vccq-max-microamp     : specifies max. load that can be drawn from vccq supply
> +- vccq2-max-microamp    : specifies max. load that can be drawn from vccq2 supply

How is this information useful?

> +- <name>-fixed-regulator : boolean property specifying that <name>-supply is a fixed regulator

No need for this. Look up the phandle and check supply's node if you 
want to know this.

> +
> +- clocks                : List of phandle and clock specifier pairs
> +- clock-names           : List of clock input name strings sorted in the same
> +                          order as the clocks property.
> +			  "core", "sclk_unipro_main", "ref" and ref_parent
> +
> +- freq-table-hz		: Array of <min max> operating frequencies stored in the same
> +			  order as the clocks property. If this property is not
> +			  defined or a value in the array is "0" then it is assumed
> +			  that the frequency is set by the parent clock or a
> +			  fixed rate clock source.
> +- pclk-freq-avail-range : specifies available frequency range(min/max) for APB clock
> +- ufs,pwr-attr-mode : specifies mode value for power mode change, possible values are
> +			"FAST", "SLOW", "FAST_auto" and "SLOW_auto"

Anything before the ',' is considered a vendor prefix and 'ufs' is not a 
vendor.

If these are standard UFS properties, then they should be documented in 
a common UFS binding. On the flip side, none of the other UFS bindings 
have needed these properties, so why do you?

> +- ufs,pwr-attr-lane : specifies lane count value for power mode change
> +		      allowed values are 1 or 2
> +- ufs,pwr-attr-gear : specifies gear count value for power mode change
> +		      allowed values are 1 or 2
> +- ufs,pwr-attr-hs-series : specifies HS rate series for power mode change
> +			   can be one of "HS_rate_b" or "HS_rate_a"
> +- ufs,pwr-local-l2-timer : specifies array of local UNIPRO L2 timer values
> +			   3 timers supported
> +			   <FC0ProtectionTimeOutVal,TC0ReplayTimeOutVal, AFC0ReqTimeOutVal>
> +- ufs,pwr-remote-l2-timer : specifies array of remote UNIPRO L2 timer values
> +			   3 timers supported
> +			   <FC0ProtectionTimeOutVal,TC0ReplayTimeOutVal, AFC0ReqTimeOutVal>
> +- ufs-rx-adv-fine-gran-sup_en : specifies support of fine granularity of MPHY,
> +			      this is a boolean property.
> +- ufs-rx-adv-fine-gran-step : specifies granularity steps of MPHY,
> +			      allowed step size is 0 to 3
> +- ufs-rx-adv-min-activate-time-cap : specifies rx advanced minimum activate time of MPHY
> +				     range is 1 to 9
> +- ufs-pa-granularity : specifies Granularity for PA_TActivate and PA_Hibern8Time
> +- ufs-pa-tacctivate : specifies time to wake-up remote M-RX
> +- ufs-pa-hibern8time : specifies minimum time to wait in HIBERN8 state
> +
> +Note: If above properties are not defined it can be assumed that the supply
> +regulators or clocks are always on.
> +
> +Example:
> +	ufshc@0x15570000 {
> +		compatible = "samsung,exynos7-ufs";
> +		reg = <0x15570000 0x100>,
> +		      <0x15570100 0x100>,
> +		      <0x15571000 0x200>,
> +		      <0x15572000 0x300>;
> +		reg-names = "hci", "vs_hci", "unipro", "ufsp";
> +		interrupts = <0 200 0>;
> +
> +		vdd-hba-supply = <&xxx_reg0>;
> +		vdd-hba-fixed-regulator;
> +		vcc-supply = <&xxx_reg1>;
> +		vcc-supply-1p8;
> +		vccq-supply = <&xxx_reg2>;
> +		vccq2-supply = <&xxx_reg3>;
> +		vcc-max-microamp = 500000;
> +		vccq-max-microamp = 200000;
> +		vccq2-max-microamp = 200000;
> +
> +		clocks = <&core 0>, <&ref 0>, <&iface 0>;
> +		clock-names = "core", "sclk_unipro_main", "ref", "ref_parent";
> +		freq-table-hz = <100000000 200000000>, <0 0>, <0 0>, <0 0>;
> +
> +		pclk-freq-avail-range = <70000000 133000000>;
> +
> +		ufs,pwr-attr-mode = "FAST";
> +		ufs,pwr-attr-lane = <2>;
> +		ufs,pwr-attr-gear = <2>;
> +		ufs,pwr-attr-hs-series = "HS_rate_b";
> +		ufs,pwr-local-l2-timer = <8000 28000 20000>;
> +		ufs,pwr-remote-l2-timer = <12000 32000 16000>;
> +		ufs-rx-adv-fine-gran-sup_en = <1>;
> +		ufs-rx-adv-fine-gran-step = <3>;
> +		ufs-rx-adv-min-activate-time-cap = <9>;
> +		ufs-pa-granularity = <6>;
> +		ufs-pa-tacctivate = <6>;
> +		ufs-pa-hibern8time = <20>;
> +	};
> -- 
> 2.17.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
  2020-04-05  1:48                       ` Alim Akhtar
@ 2020-04-05  8:11                         ` Paweł Chmiel
  0 siblings, 0 replies; 22+ messages in thread
From: Paweł Chmiel @ 2020-04-05  8:11 UTC (permalink / raw)
  To: Alim Akhtar, robh+dt, devicetree, linux-scsi
  Cc: linux-samsung-soc, martin.petersen, linux-kernel, krzk,
	kwmad.kim, avri.altman, cang, stanley.chu, linux-arm-kernel

On Sun, 2020-04-05 at 07:18 +0530, Alim Akhtar wrote:
Hi Alim
> Hi Pawel,
> 
> > -----Original Message-----
> > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > Sent: 05 April 2020 01:56
> > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > Cc: krzk@kernel.org; avri.altman@wdc.com; martin.petersen@oracle.com;
> > kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> > cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > 
> > On Sat, 2020-04-04 at 21:33 +0200, Paweł Chmiel wrote:
> > > On Sat, 2020-04-04 at 23:45 +0530, Alim Akhtar wrote:
> > > Hi Alim,
> > > > Hi Pawel,
> > > > 
> > > > > -----Original Message-----
> > > > > From: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > > > > Sent: 03 April 2020 22:22
> > > > > To: Alim Akhtar <alim.akhtar@samsung.com>; robh+dt@kernel.org;
> > > > > devicetree@vger.kernel.org; linux-scsi@vger.kernel.org
> > > > > Cc: krzk@kernel.org; avri.altman@wdc.com;
> > > > > martin.petersen@oracle.com; kwmad.kim@samsung.com;
> > > > > stanley.chu@mediatek.com; cang@codeaurora.org;
> > > > > linux-samsung-soc@vger.kernel.org; linux-arm-
> > > > > kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> > > > > Subject: Re: [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7
> > > > > 
> > > > > Hi Alim
> > > > > 
> > > > > Looking at vendor sources, my device is using the same gpios for
> > > > > urfs_rst_n and ufs_refclk_out like Espresso (with one difference -
> > > > > ufs_rst_n shouldn't be pulled up).
> > > > > 
> > > > > About regulators (it would be easier if dts would have all regulators).
> > > > > It's also using s2mps15 as Espresso, but it vendor dts had only 8
> > > > > (of
> > > > > 10 possible bucks, one missing was for UFS) and 14 ldos (of 27
> > > > > possible), where almost all rails are connected to something.
> > > > > 
> > > > > I'm wondering how it's working on Espresso, because when adding
> > > > > correct regulators for ufs (vccq = buck10 from s2mps15, always
> > > > > enabled for testing plus vccq2 and vccq = two regulators enabled
> > > > > by one gpio, enabled at boot by firmware), ufs wasn't still
> > > > > working because it was then failing at defer probe (s2mps15 was
> > > > > probed after ufs)
> > > > > 
> > > > > [    0.962482] exynos-ufshc 15570000.ufs: ufshcd_get_vreg: vccq get
> > > > > failed, err=-517
> > > > > 
> > > > As I said, this is very specific to the board, on Espresso we have LDO12
> > connected to UFS_RESETn.
> > > > Either make all of them as always-on, or just disabled s2mps15
> > > > (default voltage supply should be ok, unless bootloader on your
> > > > board does have messed too much with PMIC)
> > > > 
> > > > > After that boot would just stop/hang.
> > > > > 
> > > > > After making a "dirty fix" by making s2mps15 regulator driver use
> > > > > subsys_initcall (like in vendor sources) and ufs late_initcall (to
> > > > > give it more time to setup and get it working and solve it later),
> > > > > i had to mark following clocks as CLK_IGNORE_UNUSED to be able to
> > > > > bring link up (it replicates setting done by vendor kernel, which
> > > > > enables them on boot):
> > > > > - "phyclk_ufs20_rx1_symbol_user"
> > > > > - "phyclk_ufs20_rx0_symbol_user"
> > > > > - "phyclk_ufs20_tx0_symbol_user"
> > > > > 
> > > > Coming to these clocks, all these are supplied by default, my best
> > > > guess is since you are using an actual product (S6 edge), they might have
> > optimized for power saving And most likely all clock might be  gated initially. In
> > my case all are set to default.
> > > > I have attached a small change in the exynos7 dts and phy driver clock
> > handling, please try this attached patch and let me know if this helps in removing
> > some of your hacks.
> > > > In the later SoCs these clocks are not in this form, so I didn't included in my
> > current patch set, If this works for your, will add as an optional for
> > exynos7/7420.
> > > > I also assume you are using clk-exynos7.c and my posted ufs driver.
> > > Yes, i'm using clk-exynos7 (and other exynos7 drivers/dts/etc).
> > > It would be great if someone could say how exynos7 and exynos7420 are
> > > similar. For now it looks like that only difference is that exynos7
> > > has only 4 cores (a57) where 7420 has 4xa53 + 4xa57.
> > > It would be very valuable information for me so i could know how much
> > > i could reuse my device.
> > > > > Now it's able to bring both device and link, but it fails at
> > > > > ufshcd_uic_change_pwr_mode.
> > > > > 
> > > > Can you please use the exact ufs and ufs-phy device node as in my patch?
> > > With Your patch + removed my changes to clocks (removed fix for wrong
> > > clock order in dts + removed CLK_IGNORE_UNUSED from symbol clocks in
> > > clk-exynos7) it's finally able to detect my UFS device!!
> > > 
> 
> Wow, great to know that UFS device started working for you on S6.
> 
> > > (but of fails later...with constant error spam in kernel log).
> > > 
> > > [    1.383481] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: Unable
> > > to find vdd-hba-supply regulator, assuming enabled
> > > [    1.390060] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> > > to find vcc-max-microamp
> > > [    1.398465] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> > > to find vccq-max-microamp
> > > [    1.406968] exynos-ufshc 15570000.ufs: ufshcd_populate_vreg: unable
> > > to find vccq2-max-microamp
> > > [    1.415569] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > > core_clk, rate: 100000000
> > > [    1.423715] exynos-ufshc 15570000.ufs: ufshcd_init_clocks: clk:
> > > sclk_unipro_main, rate: 167000000
> > > [    1.432569] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > > core_clk enabled
> > > [    1.440205] exynos-ufshc 15570000.ufs: __ufshcd_setup_clocks: clk:
> > > sclk_unipro_main enabled
> > > [    1.449613] scsi host0: ufshcd
> > > [    1.452179] samsung-ufs-phy 15571800.ufs-phy: MPHY ref_clk_rate =
> > > 26000000
> > > [    1.458448] samsung-ufs-phy 15571800.ufs-phy: MPHY
> > > ref_parent_clk_rate = 26000000
> > > [    1.487288] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > > TX]: gear=[1, 1], lane[1, 1], pwr[SLOWAUTO_MODE, SLOWAUTO_MODE],
> > rate
> > > =
> > > 0
> > > [    2.025569] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > > 0x1fff error code 1
> > > [    2.025715] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd041 val
> > > 0x1fff failed 0 retries
> > > [    2.025880] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > > 0xffff error code 1
> > > [    2.027354] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd042 val
> > > 0xffff failed 0 retries
> > > [    2.035583] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > > 0x7fff error code 1
> > > [    2.043465] exynos-ufshc 15570000.ufs: dme-set: attr-id 0xd043 val
> > > 0x7fff failed 0 retries
> > > [    2.054049] exynos-ufshc 15570000.ufs: Power mode change 0 : Fast
> > > series_B G_2 L_2
> > > [    2.059261] exynos-ufshc 15570000.ufs: ufshcd_print_pwr_info:[RX,
> > > TX]: gear=[2, 2], lane[2, 2], pwr[FAST MODE, FAST MODE], rate = 2
> > > [    2.071307] exynos-ufshc 15570000.ufs: ufshcd_init_icc_levels:
> > > setting icc_level 0x0
> > > [    2.081624] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > > activate tcq with queue depth 1
> > > [    2.087576] scsi 0:0:0:49488: scsi_add_lun: correcting incorrect
> > > peripheral device type 0x0 for W-LUN 0x            c150hN
> > > [    2.098400] scsi 0:0:0:49488: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> > > E0B1  0200 PQ: 0 ANSI: 6
> > > [    2.107585] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > > activate tcq with queue depth 16
> > > [    2.115588] scsi 0:0:0:49476: scsi_add_lun: correcting incorrect
> > > peripheral device type 0x0 for W-LUN 0x            c144hN
> > > [    2.126519] scsi 0:0:0:49476: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> > > E0B1  0200 PQ: 0 ANSI: 6
> > > [    2.135534] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > > activate tcq with queue depth 1
> > > [    2.143612] scsi 0:0:0:49456: scsi_add_lun: correcting incorrect
> > > peripheral device type 0x0 for W-LUN 0x            c130hN
> > > [    2.154543] scsi 0:0:0:49456: Well-known LUN    SAMSUNG  KLUBG4G1BD-
> > > E0B1  0200 PQ: 0 ANSI: 6
> > > [    2.163597] exynos-ufshc 15570000.ufs: ufshcd_set_queue_depth:
> > > activate tcq with queue depth 16
> > > [    2.171721] scsi 0:0:0:0: Direct-Access     SAMSUNG  KLUBG4G1BD-
> > > E0B1  0200 PQ: 0 ANSI: 6
> > > [    2.180352] exynos-ufshc 15570000.ufs: OCS error from controller = 7
> > > for tag 0
> > > [    2.186921] host_regs: 00000000: 0383ff0f 00000000 00000200 00000000
> > > [    2.193230] host_regs: 00000010: 00000101 00007fce 00000c96 00000000
> > > [    2.199565] host_regs: 00000020: 00000000 00030e75 00000000 00000000
> > > [    2.205899] host_regs: 00000030: 0000010f 00000000 80000010 00000000
> > > [    2.212234] host_regs: 00000040: 00000000 00000000 00000000 00000000
> > > [    2.218568] host_regs: 00000050: f8d64000 00000000 00000000 00000000
> > > [    2.224903] host_regs: 00000060: 00000001 00000000 00000000 00000000
> > > [    2.231237] host_regs: 00000070: f8da2000 00000000 00000000 00000000
> > > [    2.237572] host_regs: 00000080: 00000001 00000000 00000000 00000000
> > > [    2.243907] host_regs: 00000090: 00000002 95190000 00000000 00000000
> > > [    2.250242] exynos-ufshc 15570000.ufs: hba->ufs_version = 0x200,
> > > hba->capabilities = 0x383ff0f
> > > 
> > > Full bootlog
> > > https://protect2.fireeye.com/url?k=edbae146-b069b8f8-edbb6a09-0cc47a31
> > > ba82-
> > 8b13b1e4caed34d7&q=1&u=https%3A%2F%2Fgist.github.com%2FPabloPL%2F
> > > 0bcb24492f4ab6e9703c2a4ea20ceb18 kernel source:
> > > https://protect2.fireeye.com/url?k=75038dec-28d0d452-750206a3-0cc47a31
> > > ba82-
> > 4c366bec6fc01e64&q=1&u=https%3A%2F%2Fgithub.com%2FPabloPL%2Flinux
> > > %2Ftree%2Fufs-mainline dts file: exynos7-zeroflt.dts (it should be
> > > zerolt, but will be fixed/changed later).
> > 
> > Actually, after waiting enough time (about 15 or even more sec of that error
> > "spam"), was able to mount partitions and manipulate files there.
> > 
> You need below patch and  a change in the ufs driver:
> https://www.spinics.net/lists/linux-scsi/msg138501.html
> 
> And
> 
> diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c
> index ce2c3d674e4b..c6332deff03a 100644
> --- a/drivers/scsi/ufs/ufs-exynos.c
> +++ b/drivers/scsi/ufs/ufs-exynos.c
> @@ -1359,7 +1359,8 @@ struct exynos_ufs_drv_data exynos_ufs_drvs = {
>         .quirks                 = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
>                                   UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
>                                   UFSHCI_QUIRK_BROKEN_HCE |
> -                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR,
> +                                 UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
> +                                 UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR,
>         .opts                   = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL |
>                                   EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
>                                   EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
> 
> > So for me the only issue to solve are defered probe when regulators are not yet
> > found (for example when pmic is probed after ufs) and not sure what about that
> > errors (despite working ufs).
> > 
> The error will go away with the above changes, about regulators, you need to figure it out, as I am not aware of Galaxy S6 PMIC schemes.
> I also seek your Tested-by tag on these patches .
Checked with those two patches applied, error is gone.
You can add my Tested-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
to all patches.

Thanks
> 
> > Thanks for all
> 
> Thanks for helping in testing.
> > > Thanks
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: [PATCH v4 1/5] dt-bindings: phy: Document Samsung UFS PHY bindings
  2020-04-05  1:54       ` Rob Herring
@ 2020-04-07  0:28         ` Alim Akhtar
  0 siblings, 0 replies; 22+ messages in thread
From: Alim Akhtar @ 2020-04-07  0:28 UTC (permalink / raw)
  To: 'Rob Herring'
  Cc: devicetree, linux-samsung-soc, linux-scsi, martin.petersen,
	linux-kernel, krzk, kwmad.kim, avri.altman, cang, stanley.chu,
	linux-arm-kernel

Hi Rob,

> -----Original Message-----
> From: Rob Herring <robh@kernel.org>
> Sent: 05 April 2020 07:24
> To: Alim Akhtar <alim.akhtar@samsung.com>
> Cc: devicetree@vger.kernel.org; linux-scsi@vger.kernel.org;
krzk@kernel.org;
> avri.altman@wdc.com; martin.petersen@oracle.com;
> kwmad.kim@samsung.com; stanley.chu@mediatek.com;
> cang@codeaurora.org; linux-samsung-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v4 1/5] dt-bindings: phy: Document Samsung UFS PHY
> bindings
> 
> On Fri, Mar 27, 2020 at 10:36:34PM +0530, Alim Akhtar wrote:
> > This patch documents Samsung UFS PHY device tree bindings
> >
> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > ---
> >  .../bindings/phy/samsung,ufs-phy.yaml         | 67 +++++++++++++++++++
> >  1 file changed, 67 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
> >
> > diff --git
> > a/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
> > b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
> > new file mode 100644
> > index 000000000000..41ba481ecc76
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
> > @@ -0,0 +1,67 @@
> > +# SPDX-License-Identifier: (GPL-2.0)
> 
> Dual license new bindings:
> 
> (GPL-2.0-only OR BSD-2-Clause)
> 
Sure will update.

> > +%YAML 1.2
> > +---
> > +$id:
> > +https://protect2.fireeye.com/url?k=91cb53a2-cc1b5b6e-91cad8ed-000babf
> > +f3793-
> 448c7d85bdf69f5a&q=1&u=http%3A%2F%2Fdevicetree.org%2Fschemas%2F
> > +phy%2Fsamsung%2Cufs-phy.yaml%23
> > +$schema:
> > +https://protect2.fireeye.com/url?k=a8ce57c7-f51e5f0b-a8cfdc88-000babf
> > +f3793-fbe649ab0853d701&q=1&u=http%3A%2F%2Fdevicetree.org%2Fmeta-
> schem
> > +as%2Fcore.yaml%23
> > +
> > +title: Samsung SoC series UFS PHY Device Tree Bindings
> > +
> > +maintainers:
> > +  - Alim Akhtar <alim.akhtar@samsung.com>
> > +
> > +properties:
> > +  "#phy-cells":
> > +    const: 0
> > +
> > +  compatible:
> > +    enum:
> > +      - samsung,exynos7-ufs-phy
> > +
> > +  reg:
> > +    maxItems: 1
> > +    description: PHY base register address
> > +
> > +  reg-names:
> > +    items:
> > +      - const: phy-pma
> > +
> > +  clocks:
> > +    items:
> > +      - description: PLL reference clock
> > +      - description: Referencec clock parrent
> > +
> > +  clock-names:
> > +    items:
> > +      - const: ref_clk_parent
> > +      - const: ref_clk
> 
> Doesn't match what 'clocks' says.
> 
Will correct.

> Also, why do you need the parent in DT? Just use clk_get_parent(). DT
should
> reflect actual h/w clock connections (not what the driver happens to
need).
> Also, there's the assigned-clocks binding.
> 
Some of the platform deviates from the normal clock trees and need to force
a different parent. To get such parent added this.
I will explore a bit more on this, and check about assigned-clocks binding.
This is also an optional clock, so will change accordingly

> > +
> > +  samsung,pmu-syscon:
> > +    $ref: '/schemas/types.yaml#/definitions/phandle'
> > +    description: phandle for PMU system controller interface, used to
> > +                 control pmu registers for power isolation
> 
> We have a binding for power domains. Use that for power isolation.
> 
Let me have a look on that, if power domains bindings can be use here, this
is same way other Exynos binding is defined w.r.t. pmu-syscon.

> > +
> > +required:
> > +  - "#phy-cells"
> > +  - compatible
> > +  - reg
> > +  - reg-names
> > +  - clocks
> > +  - clock-names
> > +  - samsung,pmu-syscon
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/exynos7-clk.h>
> > +
> > +    ufs_phy: ufs-phy@15571800 {
> > +        compatible = "samsung,exynos7-ufs-phy";
> > +        reg = <0x15571800 0x240>;
> > +        reg-names = "phy-pma";
> > +        samsung,pmu-syscon = <&pmu_system_controller>;
> > +        #phy-cells = <0>;
> > +        clocks = <&clock_fsys1 MOUT_FSYS1_PHYCLK_SEL1>,
> > +                 <&clock_top1 CLK_SCLK_PHY_FSYS1_26M>;
> > +        clock-names = "ref_clk_parent",
> > +                      "ref_clk";
> > +    };
> > +...
> >
> > base-commit: fb33c6510d5595144d585aa194d377cf74d31911
> > --
> > 2.17.1
> >


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v4 3/5] Documentation: devicetree: ufs: Add DT bindings for exynos UFS host controller
  2020-04-05  2:02       ` Rob Herring
@ 2020-04-12  5:41         ` Alim Akhtar
  0 siblings, 0 replies; 22+ messages in thread
From: Alim Akhtar @ 2020-04-12  5:41 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, linux-samsung-soc, linux-scsi, Martin K. Petersen,
	open list, Krzysztof Kozlowski, Kiwoong Kim, Avri Altman,
	Can Guo, Alim Akhtar, Stanley Chu, linux-arm-kernel

Hi Rob

On Sun, Apr 5, 2020 at 7:33 AM Rob Herring <robh@kernel.org> wrote:
>
> On Fri, Mar 27, 2020 at 10:36:36PM +0530, Alim Akhtar wrote:
> > This adds Exynos Universal Flash Storage (UFS) Host Controller DT bindings.
>
> Why the inconsistent subject. 'dt-bindings: ...' please.
>
Sure will update
> >
> > Signed-off-by: Seungwon Jeon <essuuj@gmail.com>
> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> > ---
> >  .../devicetree/bindings/ufs/ufs-exynos.txt    | 104 ++++++++++++++++++
> >  1 file changed, 104 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/ufs/ufs-exynos.txt
>
> Use DT schema format. Not sure why you'd do that for one and not the
> other...
>
Yah, this is my 1st attempt to write binding in DT schema format, few
things were not clear, now with your review, things got clear. I will
keep the common UFS binding as it is and change exynos UFS binding in
schema format.
Will post the changes soon.

> >
> > diff --git a/Documentation/devicetree/bindings/ufs/ufs-exynos.txt b/Documentation/devicetree/bindings/ufs/ufs-exynos.txt
> > new file mode 100644
> > index 000000000000..08e2d1497b1b
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/ufs/ufs-exynos.txt
> > @@ -0,0 +1,104 @@
> > +* Exynos Universal Flash Storage (UFS) Host Controller
> > +
> > +UFSHC nodes are defined to describe on-chip UFS host controllers.
> > +Each UFS controller instance should have its own node.
> > +
> > +Required properties:
> > +- compatible        : compatible name, contains "samsung,exynos7-ufs"
> > +- interrupts        : <interrupt mapping for UFS host controller IRQ>
> > +- reg               : Should contain HCI, vendor specific, UNIPRO and
> > +                   UFS protector address space
> > +- reg-names      : "hci", "vs_hci", "unipro", "ufsp";
> > +
> > +Optional properties:
> > +- vdd-hba-supply        : phandle to UFS host controller supply regulator node
> > +- vcc-supply            : phandle to VCC supply regulator node
> > +- vccq-supply           : phandle to VCCQ supply regulator node
> > +- vccq2-supply          : phandle to VCCQ2 supply regulator node
> > +- vcc-supply-1p8        : For embedded UFS devices, valid VCC range is 1.7-1.95V
> > +                          or 2.7-3.6V. This boolean property when set, specifies
> > +                       to use low voltage range of 1.7-1.95V. Note for external
> > +                       UFS cards this property is invalid and valid VCC range is
> > +                       always 2.7-3.6V.
>
> The supply for vcc-supply should be restricted to the valid range and
> this is not needed.
>
For now, I will leave these common binding as it is.
> > +- vcc-max-microamp      : specifies max. load that can be drawn from vcc supply
> > +- vccq-max-microamp     : specifies max. load that can be drawn from vccq supply
> > +- vccq2-max-microamp    : specifies max. load that can be drawn from vccq2 supply
>
> How is this information useful?
>
> > +- <name>-fixed-regulator : boolean property specifying that <name>-supply is a fixed regulator
>
> No need for this. Look up the phandle and check supply's node if you
> want to know this.
>
ok
> > +
> > +- clocks                : List of phandle and clock specifier pairs
> > +- clock-names           : List of clock input name strings sorted in the same
> > +                          order as the clocks property.
> > +                       "core", "sclk_unipro_main", "ref" and ref_parent
> > +
> > +- freq-table-hz              : Array of <min max> operating frequencies stored in the same
> > +                       order as the clocks property. If this property is not
> > +                       defined or a value in the array is "0" then it is assumed
> > +                       that the frequency is set by the parent clock or a
> > +                       fixed rate clock source.
> > +- pclk-freq-avail-range : specifies available frequency range(min/max) for APB clock
> > +- ufs,pwr-attr-mode : specifies mode value for power mode change, possible values are
> > +                     "FAST", "SLOW", "FAST_auto" and "SLOW_auto"
>
> Anything before the ',' is considered a vendor prefix and 'ufs' is not a
> vendor.
>
> If these are standard UFS properties, then they should be documented in
> a common UFS binding. On the flip side, none of the other UFS bindings
> have needed these properties, so why do you?
>
Yah understood, these are not UFS common properties, I will change the
driver instead to handle them.
This will also simply exynos UFS binding.

> > +- ufs,pwr-attr-lane : specifies lane count value for power mode change
> > +                   allowed values are 1 or 2
> > +- ufs,pwr-attr-gear : specifies gear count value for power mode change
> > +                   allowed values are 1 or 2
> > +- ufs,pwr-attr-hs-series : specifies HS rate series for power mode change
> > +                        can be one of "HS_rate_b" or "HS_rate_a"
> > +- ufs,pwr-local-l2-timer : specifies array of local UNIPRO L2 timer values
> > +                        3 timers supported
> > +                        <FC0ProtectionTimeOutVal,TC0ReplayTimeOutVal, AFC0ReqTimeOutVal>
> > +- ufs,pwr-remote-l2-timer : specifies array of remote UNIPRO L2 timer values
> > +                        3 timers supported
> > +                        <FC0ProtectionTimeOutVal,TC0ReplayTimeOutVal, AFC0ReqTimeOutVal>
> > +- ufs-rx-adv-fine-gran-sup_en : specifies support of fine granularity of MPHY,
> > +                           this is a boolean property.
> > +- ufs-rx-adv-fine-gran-step : specifies granularity steps of MPHY,
> > +                           allowed step size is 0 to 3
> > +- ufs-rx-adv-min-activate-time-cap : specifies rx advanced minimum activate time of MPHY
> > +                                  range is 1 to 9
> > +- ufs-pa-granularity : specifies Granularity for PA_TActivate and PA_Hibern8Time
> > +- ufs-pa-tacctivate : specifies time to wake-up remote M-RX
> > +- ufs-pa-hibern8time : specifies minimum time to wait in HIBERN8 state
> > +
> > +Note: If above properties are not defined it can be assumed that the supply
> > +regulators or clocks are always on.
> > +
> > +Example:
> > +     ufshc@0x15570000 {
> > +             compatible = "samsung,exynos7-ufs";
> > +             reg = <0x15570000 0x100>,
> > +                   <0x15570100 0x100>,
> > +                   <0x15571000 0x200>,
> > +                   <0x15572000 0x300>;
> > +             reg-names = "hci", "vs_hci", "unipro", "ufsp";
> > +             interrupts = <0 200 0>;
> > +
> > +             vdd-hba-supply = <&xxx_reg0>;
> > +             vdd-hba-fixed-regulator;
> > +             vcc-supply = <&xxx_reg1>;
> > +             vcc-supply-1p8;
> > +             vccq-supply = <&xxx_reg2>;
> > +             vccq2-supply = <&xxx_reg3>;
> > +             vcc-max-microamp = 500000;
> > +             vccq-max-microamp = 200000;
> > +             vccq2-max-microamp = 200000;
> > +
> > +             clocks = <&core 0>, <&ref 0>, <&iface 0>;
> > +             clock-names = "core", "sclk_unipro_main", "ref", "ref_parent";
> > +             freq-table-hz = <100000000 200000000>, <0 0>, <0 0>, <0 0>;
> > +
> > +             pclk-freq-avail-range = <70000000 133000000>;
> > +
> > +             ufs,pwr-attr-mode = "FAST";
> > +             ufs,pwr-attr-lane = <2>;
> > +             ufs,pwr-attr-gear = <2>;
> > +             ufs,pwr-attr-hs-series = "HS_rate_b";
> > +             ufs,pwr-local-l2-timer = <8000 28000 20000>;
> > +             ufs,pwr-remote-l2-timer = <12000 32000 16000>;
> > +             ufs-rx-adv-fine-gran-sup_en = <1>;
> > +             ufs-rx-adv-fine-gran-step = <3>;
> > +             ufs-rx-adv-min-activate-time-cap = <9>;
> > +             ufs-pa-granularity = <6>;
> > +             ufs-pa-tacctivate = <6>;
> > +             ufs-pa-hibern8time = <20>;
> > +     };
> > --
> > 2.17.1
> >



-- 
Regards,
Alim

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2020-04-12  5:42 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20200327171411epcas5p17f4457f9fd61800257607059b9506fb2@epcas5p1.samsung.com>
2020-03-27 17:06 ` [PATCH v4 0/5] exynos-ufs: Add support for UFS HCI Alim Akhtar
     [not found]   ` <CGME20200327171414epcas5p1460e932c0bc98f31ebdd115218b4fd49@epcas5p1.samsung.com>
2020-03-27 17:06     ` [PATCH v4 1/5] dt-bindings: phy: Document Samsung UFS PHY bindings Alim Akhtar
2020-04-05  1:54       ` Rob Herring
2020-04-07  0:28         ` Alim Akhtar
     [not found]   ` <CGME20200327171416epcas5p43133a28159ef24b145fcc8f3df102dde@epcas5p4.samsung.com>
2020-03-27 17:06     ` [PATCH v4 2/5] phy: samsung-ufs: add UFS PHY driver for samsung SoC Alim Akhtar
     [not found]   ` <CGME20200327171418epcas5p4b85bea273e17c05a7edca58f528c435a@epcas5p4.samsung.com>
2020-03-27 17:06     ` [PATCH v4 3/5] Documentation: devicetree: ufs: Add DT bindings for exynos UFS host controller Alim Akhtar
2020-04-05  2:02       ` Rob Herring
2020-04-12  5:41         ` Alim Akhtar
     [not found]   ` <CGME20200327171420epcas5p490e1e6d090a540eaf050e0728a39ba25@epcas5p4.samsung.com>
2020-03-27 17:06     ` [PATCH v4 4/5] scsi: ufs-exynos: add UFS host support for Exynos SoCs Alim Akhtar
2020-03-28 11:28       ` Avri Altman
2020-04-02 15:08         ` Alim Akhtar
     [not found]   ` <CGME20200327171423epcas5p485d227f19e45999ad9b42b21d2864e4a@epcas5p4.samsung.com>
2020-03-27 17:06     ` [PATCH v4 5/5] arm64: dts: Add node for ufs exynos7 Alim Akhtar
2020-03-28 13:30       ` Paweł Chmiel
2020-03-28 15:35         ` Alim Akhtar
2020-03-28 17:46           ` Paweł Chmiel
2020-03-29 15:35             ` Alim Akhtar
2020-04-03 16:52               ` Paweł Chmiel
2020-04-04 18:15                 ` Alim Akhtar
2020-04-04 19:33                   ` Paweł Chmiel
2020-04-04 20:25                     ` Paweł Chmiel
2020-04-05  1:48                       ` Alim Akhtar
2020-04-05  8:11                         ` Paweł Chmiel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).