phy: samsung-ufs: convert phy clk usage to clk_bulk API
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@samsung.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Link: https://lore.kernel.org/r/20220706020255.151177-2-chanho61.park@samsung.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Родитель
c1ab64aaac
Коммит
8d5bb683d5
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
int i;
|
||||
const struct samsung_ufs_phy_drvdata *drvdata = phy->drvdata;
|
||||
int num_clks = drvdata->num_clks;
|
||||
|
||||
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");
|
||||
phy->clks = devm_kcalloc(phy->dev, num_clks, sizeof(*phy->clks),
|
||||
GFP_KERNEL);
|
||||
if (!phy->clks)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = clk_prepare_enable(phy->ref_clk);
|
||||
if (ret) {
|
||||
dev_err(phy->dev, "%s: ref_clk enable failed %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
for (i = 0; i < num_clks; i++)
|
||||
phy->clks[i].id = drvdata->clk_list[i];
|
||||
|
||||
dev_dbg(phy->dev, "UFS MPHY ref_clk_rate = %ld\n", clk_get_rate(phy->ref_clk));
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче