[PATCH 1/3] phy: samsung-ufs: convert phy clk usage to clk_bulk API

Chanho Park chanho61.park at samsung.com
Mon Jul 4 23:54:38 PDT 2022


Instead of using separated clock manipulation, this converts the phy
clock usage to be clk_bulk APIs. By using this, we can completely
remove has_symbol_clk check and symbol clk variables.
Furthermore, clk_get should be moved to probe because there is no need
to get them in the phy_init callback.

Signed-off-by: Chanho Park <chanho61.park at samsung.com>
---
 drivers/phy/samsung/phy-exynos7-ufs.c      |  7 +-
 drivers/phy/samsung/phy-exynosautov9-ufs.c |  7 +-
 drivers/phy/samsung/phy-fsd-ufs.c          |  7 +-
 drivers/phy/samsung/phy-samsung-ufs.c      | 99 +++++-----------------
 drivers/phy/samsung/phy-samsung-ufs.h      | 10 +--
 5 files changed, 42 insertions(+), 88 deletions(-)

diff --git a/drivers/phy/samsung/phy-exynos7-ufs.c b/drivers/phy/samsung/phy-exynos7-ufs.c
index 72854336f59d..a982e7c128c5 100644
--- a/drivers/phy/samsung/phy-exynos7-ufs.c
+++ b/drivers/phy/samsung/phy-exynos7-ufs.c
@@ -68,6 +68,10 @@ static const struct samsung_ufs_phy_cfg *exynos7_ufs_phy_cfgs[CFG_TAG_MAX] = {
 	[CFG_POST_PWR_HS]	= exynos7_post_pwr_hs_cfg,
 };
 
+static const char * const exynos7_ufs_phy_clks[] = {
+	"tx0_symbol_clk", "rx0_symbol_clk", "rx1_symbol_clk", "ref_clk",
+};
+
 const struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
 	.cfgs = exynos7_ufs_phy_cfgs,
 	.isol = {
@@ -75,6 +79,7 @@ const struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
 		.mask = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_MASK,
 		.en = EXYNOS7_EMBEDDED_COMBO_PHY_CTRL_EN,
 	},
-	.has_symbol_clk = 1,
+	.clk_list = exynos7_ufs_phy_clks,
+	.num_clks = ARRAY_SIZE(exynos7_ufs_phy_clks),
 	.cdr_lock_status_offset = EXYNOS7_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
 };
diff --git a/drivers/phy/samsung/phy-exynosautov9-ufs.c b/drivers/phy/samsung/phy-exynosautov9-ufs.c
index 2b256070d657..49e2bcbef0b4 100644
--- a/drivers/phy/samsung/phy-exynosautov9-ufs.c
+++ b/drivers/phy/samsung/phy-exynosautov9-ufs.c
@@ -57,6 +57,10 @@ static const struct samsung_ufs_phy_cfg *exynosautov9_ufs_phy_cfgs[CFG_TAG_MAX]
 	[CFG_PRE_PWR_HS]	= exynosautov9_pre_pwr_hs_cfg,
 };
 
+static const char * const exynosautov9_ufs_phy_clks[] = {
+	"ref_clk",
+};
+
 const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = {
 	.cfgs = exynosautov9_ufs_phy_cfgs,
 	.isol = {
@@ -64,6 +68,7 @@ const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = {
 		.mask = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_MASK,
 		.en = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CTRL_EN,
 	},
-	.has_symbol_clk = 0,
+	.clk_list = exynosautov9_ufs_phy_clks,
+	.num_clks = ARRAY_SIZE(exynosautov9_ufs_phy_clks),
 	.cdr_lock_status_offset = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
 };
diff --git a/drivers/phy/samsung/phy-fsd-ufs.c b/drivers/phy/samsung/phy-fsd-ufs.c
index c78b6c16027d..d36cabd53434 100644
--- a/drivers/phy/samsung/phy-fsd-ufs.c
+++ b/drivers/phy/samsung/phy-fsd-ufs.c
@@ -46,6 +46,10 @@ static const struct samsung_ufs_phy_cfg *fsd_ufs_phy_cfgs[CFG_TAG_MAX] = {
 	[CFG_POST_PWR_HS]	= fsd_post_pwr_hs_cfg,
 };
 
+static const char * const fsd_ufs_phy_clks[] = {
+	"ref_clk",
+};
+
 const struct samsung_ufs_phy_drvdata fsd_ufs_phy = {
 	.cfgs = fsd_ufs_phy_cfgs,
 	.isol = {
@@ -53,6 +57,7 @@ const struct samsung_ufs_phy_drvdata fsd_ufs_phy = {
 		.mask = FSD_EMBEDDED_COMBO_PHY_CTRL_MASK,
 		.en = FSD_EMBEDDED_COMBO_PHY_CTRL_EN,
 	},
-	.has_symbol_clk = 0,
+	.clk_list = fsd_ufs_phy_clks,
+	.num_clks = ARRAY_SIZE(fsd_ufs_phy_clks),
 	.cdr_lock_status_offset = FSD_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
 };
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
index e4334529ffbc..14cce2f2487e 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.c
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -131,73 +131,21 @@ static int samsung_ufs_phy_calibrate(struct phy *phy)
 	return err;
 }
 
-static int samsung_ufs_phy_symbol_clk_init(struct samsung_ufs_phy *phy)
-{
-	int ret;
-
-	phy->tx0_symbol_clk = devm_clk_get(phy->dev, "tx0_symbol_clk");
-	if (IS_ERR(phy->tx0_symbol_clk)) {
-		dev_err(phy->dev, "failed to get tx0_symbol_clk clock\n");
-		return PTR_ERR(phy->tx0_symbol_clk);
-	}
-
-	phy->rx0_symbol_clk = devm_clk_get(phy->dev, "rx0_symbol_clk");
-	if (IS_ERR(phy->rx0_symbol_clk)) {
-		dev_err(phy->dev, "failed to get rx0_symbol_clk clock\n");
-		return PTR_ERR(phy->rx0_symbol_clk);
-	}
-
-	phy->rx1_symbol_clk = devm_clk_get(phy->dev, "rx1_symbol_clk");
-	if (IS_ERR(phy->rx1_symbol_clk)) {
-		dev_err(phy->dev, "failed to get rx1_symbol_clk clock\n");
-		return PTR_ERR(phy->rx1_symbol_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_disable_tx0_clk;
-	}
-
-	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_disable_rx0_clk;
-	}
-
-	return 0;
-
-out_disable_rx0_clk:
-	clk_disable_unprepare(phy->rx0_symbol_clk);
-out_disable_tx0_clk:
-	clk_disable_unprepare(phy->tx0_symbol_clk);
-out:
-	return ret;
-}
-
 static int samsung_ufs_phy_clks_init(struct samsung_ufs_phy *phy)
 {
-	int ret;
-
-	phy->ref_clk = devm_clk_get(phy->dev, "ref_clk");
-	if (IS_ERR(phy->ref_clk))
-		dev_err(phy->dev, "failed to get ref_clk clock\n");
+	int i;
+	const struct samsung_ufs_phy_drvdata *drvdata = phy->drvdata;
+	int num_clks = drvdata->num_clks;
 
-	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->clks = devm_kcalloc(phy->dev, num_clks, sizeof(*phy->clks),
+				 GFP_KERNEL);
+	if (!phy->clks)
+		return -ENOMEM;
 
-	dev_dbg(phy->dev, "UFS MPHY ref_clk_rate = %ld\n", clk_get_rate(phy->ref_clk));
+	for (i = 0; i < num_clks; i++)
+		phy->clks[i].id = drvdata->clk_list[i];
 
-	return 0;
+	return devm_clk_bulk_get(phy->dev, num_clks, phy->clks);
 }
 
 static int samsung_ufs_phy_init(struct phy *phy)
@@ -208,16 +156,12 @@ static int samsung_ufs_phy_init(struct phy *phy)
 	ss_phy->lane_cnt = phy->attrs.bus_width;
 	ss_phy->ufs_phy_state = CFG_PRE_INIT;
 
-	if (ss_phy->has_symbol_clk) {
-		ret = samsung_ufs_phy_symbol_clk_init(ss_phy);
-		if (ret)
-			dev_err(ss_phy->dev, "failed to set ufs phy symbol clocks\n");
+	ret = clk_bulk_prepare_enable(ss_phy->drvdata->num_clks, ss_phy->clks);
+	if (ret) {
+		dev_err(ss_phy->dev, "failed to enable ufs phy clocks\n");
+		return ret;
 	}
 
-	ret = samsung_ufs_phy_clks_init(ss_phy);
-	if (ret)
-		dev_err(ss_phy->dev, "failed to set ufs phy clocks\n");
-
 	ret = samsung_ufs_phy_calibrate(phy);
 	if (ret)
 		dev_err(ss_phy->dev, "ufs phy calibration failed\n");
@@ -258,13 +202,7 @@ static int samsung_ufs_phy_exit(struct phy *phy)
 {
 	struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
 
-	clk_disable_unprepare(ss_phy->ref_clk);
-
-	if (ss_phy->has_symbol_clk) {
-		clk_disable_unprepare(ss_phy->tx0_symbol_clk);
-		clk_disable_unprepare(ss_phy->rx0_symbol_clk);
-		clk_disable_unprepare(ss_phy->rx1_symbol_clk);
-	}
+	clk_bulk_disable_unprepare(ss_phy->drvdata->num_clks, ss_phy->clks);
 
 	return 0;
 }
@@ -330,7 +268,6 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
 	phy->dev = dev;
 	phy->drvdata = drvdata;
 	phy->cfgs = drvdata->cfgs;
-	phy->has_symbol_clk = drvdata->has_symbol_clk;
 	memcpy(&phy->isol, &drvdata->isol, sizeof(phy->isol));
 
 	if (!of_property_read_u32_index(dev->of_node, "samsung,pmu-syscon", 1,
@@ -339,6 +276,12 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
 
 	phy->lane_cnt = PHY_DEF_LANE_CNT;
 
+	err = samsung_ufs_phy_clks_init(phy);
+	if (err) {
+		dev_err(dev, "failed to get phy clocks\n");
+		goto out;
+	}
+
 	phy_set_drvdata(gen_phy, phy);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
diff --git a/drivers/phy/samsung/phy-samsung-ufs.h b/drivers/phy/samsung/phy-samsung-ufs.h
index 6320ac852f29..e122960cfee8 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.h
+++ b/drivers/phy/samsung/phy-samsung-ufs.h
@@ -109,7 +109,8 @@ struct samsung_ufs_phy_pmu_isol {
 struct samsung_ufs_phy_drvdata {
 	const struct samsung_ufs_phy_cfg **cfgs;
 	struct samsung_ufs_phy_pmu_isol isol;
-	bool has_symbol_clk;
+	const char * const *clk_list;
+	int num_clks;
 	u32 cdr_lock_status_offset;
 };
 
@@ -117,15 +118,10 @@ struct samsung_ufs_phy {
 	struct device *dev;
 	void __iomem *reg_pma;
 	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;
+	struct clk_bulk_data *clks;
 	const struct samsung_ufs_phy_drvdata *drvdata;
 	const struct samsung_ufs_phy_cfg * const *cfgs;
 	struct samsung_ufs_phy_pmu_isol isol;
-	bool has_symbol_clk;
 	u8 lane_cnt;
 	int ufs_phy_state;
 	enum phy_mode mode;
-- 
2.37.0




More information about the linux-phy mailing list