phy: samsung-ufs: support exynosauto ufs phy driver
authorChanho Park <chanho61.park@samsung.com>
Fri, 9 Jul 2021 09:45:24 +0000 (18:45 +0900)
committerVinod Koul <vkoul@kernel.org>
Tue, 20 Jul 2021 11:13:10 +0000 (16:43 +0530)
This patch adds to support phy-exynosautov9-ufs driver for ExynosAuto v9
series SoCs. The patch adds "samsung,exynosautov9-ufs-phy" compatible.
Unlike previous exynos ufs phy, the chip uses 0x50 offset as
PHY_TRSV_REG_CFG_OFFSET.

Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
Link: https://lore.kernel.org/r/20210709094524.110193-3-chanho61.park@samsung.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml
drivers/phy/samsung/Makefile
drivers/phy/samsung/phy-exynosautov9-ufs.c [new file with mode: 0644]
drivers/phy/samsung/phy-samsung-ufs.c
drivers/phy/samsung/phy-samsung-ufs.h

index 636cc50..f6ed1a0 100644 (file)
@@ -16,6 +16,7 @@ properties:
   compatible:
     enum:
       - samsung,exynos7-ufs-phy
+      - samsung,exynosautov9-ufs-phy
 
   reg:
     maxItems: 1
index 68518ae..65e4cc5 100644 (file)
@@ -5,6 +5,7 @@ obj-$(CONFIG_PHY_EXYNOS_PCIE)           += phy-exynos-pcie.o
 obj-$(CONFIG_PHY_SAMSUNG_UFS)          += phy-exynos-ufs.o
 phy-exynos-ufs-y                       += phy-samsung-ufs.o
 phy-exynos-ufs-y                       += phy-exynos7-ufs.o
+phy-exynos-ufs-y                       += phy-exynosautov9-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-exynosautov9-ufs.c b/drivers/phy/samsung/phy-exynosautov9-ufs.c
new file mode 100644 (file)
index 0000000..36398a1
--- /dev/null
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UFS PHY driver data for Samsung EXYNOSAUTO v9 SoC
+ *
+ * Copyright (C) 2021 Samsung Electronics Co., Ltd.
+ */
+
+#include "phy-samsung-ufs.h"
+
+#define EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL           0x728
+#define EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_MASK      0x1
+#define EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_EN                BIT(0)
+
+#define PHY_TRSV_REG_CFG_AUTOV9(o, v, d) \
+       PHY_TRSV_REG_CFG_OFFSET(o, v, d, 0x50)
+
+/* Calibration for phy initialization */
+static const struct samsung_ufs_phy_cfg exynosautov9_pre_init_cfg[] = {
+       PHY_COMN_REG_CFG(0x023, 0x80, PWR_MODE_ANY),
+       PHY_COMN_REG_CFG(0x01d, 0x10, PWR_MODE_ANY),
+
+       PHY_TRSV_REG_CFG_AUTOV9(0x044, 0xb5, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x04d, 0x43, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x05b, 0x20, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x05e, 0xc0, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x038, 0x12, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x059, 0x58, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x06c, 0x18, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG_AUTOV9(0x06d, 0x02, PWR_MODE_ANY),
+
+       PHY_COMN_REG_CFG(0x023, 0xc0, PWR_MODE_ANY),
+       PHY_COMN_REG_CFG(0x023, 0x00, PWR_MODE_ANY),
+
+       PHY_TRSV_REG_CFG(0x042, 0x5d, PWR_MODE_ANY),
+       PHY_TRSV_REG_CFG(0x043, 0x80, PWR_MODE_ANY),
+
+       END_UFS_PHY_CFG,
+};
+
+/* Calibration for HS mode series A/B */
+static const struct samsung_ufs_phy_cfg exynosautov9_pre_pwr_hs_cfg[] = {
+       PHY_TRSV_REG_CFG(0x032, 0xbc, PWR_MODE_HS_ANY),
+       PHY_TRSV_REG_CFG(0x03c, 0x7f, PWR_MODE_HS_ANY),
+       PHY_TRSV_REG_CFG(0x048, 0xc0, PWR_MODE_HS_ANY),
+
+       PHY_TRSV_REG_CFG(0x04a, 0x00, PWR_MODE_HS_G3_SER_B),
+       PHY_TRSV_REG_CFG(0x04b, 0x10, PWR_MODE_HS_G1_SER_B |
+                                     PWR_MODE_HS_G3_SER_B),
+       PHY_TRSV_REG_CFG(0x04d, 0x63, PWR_MODE_HS_G3_SER_B),
+
+       END_UFS_PHY_CFG,
+};
+
+static const struct samsung_ufs_phy_cfg *exynosautov9_ufs_phy_cfgs[CFG_TAG_MAX] = {
+       [CFG_PRE_INIT]          = exynosautov9_pre_init_cfg,
+       [CFG_PRE_PWR_HS]        = exynosautov9_pre_pwr_hs_cfg,
+};
+
+const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = {
+       .cfg = exynosautov9_ufs_phy_cfgs,
+       .isol = {
+               .offset = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL,
+               .mask = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_MASK,
+               .en = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_EN,
+       },
+       .has_symbol_clk = 0,
+};
index dd9ab15..602ddef 100644 (file)
@@ -347,6 +347,9 @@ static const struct of_device_id samsung_ufs_phy_match[] = {
        {
                .compatible = "samsung,exynos7-ufs-phy",
                .data = &exynos7_ufs_phy,
+       }, {
+               .compatible = "samsung,exynosautov9-ufs-phy",
+               .data = &exynosautov9_ufs_phy,
        },
        {},
 };
index 5ab6ca6..91a0e9f 100644 (file)
        .id = PHY_COMN_BLK,     \
 }
 
-#define PHY_TRSV_REG_CFG(o, v, d) {    \
+#define PHY_TRSV_REG_CFG_OFFSET(o, v, d, c) {  \
        .off_0 = PHY_APB_ADDR((o)),     \
-       .off_1 = PHY_APB_ADDR((o) + PHY_TRSV_CH_OFFSET),        \
+       .off_1 = PHY_APB_ADDR((o) + (c)),       \
        .val = (v),             \
        .desc = (d),            \
        .id = PHY_TRSV_BLK,     \
 }
 
+#define PHY_TRSV_REG_CFG(o, v, d)      \
+       PHY_TRSV_REG_CFG_OFFSET(o, v, d, PHY_TRSV_CH_OFFSET)
+
 /* UFS PHY registers */
 #define PHY_PLL_LOCK_STATUS    0x1e
 #define PHY_CDR_LOCK_STATUS    0x5e
@@ -138,5 +141,6 @@ static inline void samsung_ufs_phy_ctrl_isol(
 }
 
 extern const struct samsung_ufs_phy_drvdata exynos7_ufs_phy;
+extern const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy;
 
 #endif /* _PHY_SAMSUNG_UFS_ */