summaryrefslogtreecommitdiff
path: root/drivers/phy/samsung/phy-samsung-ufs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/samsung/phy-samsung-ufs.c')
-rw-r--r--drivers/phy/samsung/phy-samsung-ufs.c99
1 files changed, 21 insertions, 78 deletions
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 @@ out:
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);