Commit a4de58a9 authored by Peter Griffin's avatar Peter Griffin Committed by Vinod Koul

phy: samsung-ufs: ufs: Add SoC callbacks for calibration and clk data recovery

Some SoCs like gs101 don't fit in well with the existing pll lock and
clock data recovery (CDR) callback used by existing exynos platforms.

Allow SoCs to specifify and implement their own calibration and CDR
functions that can be called by the generic samsung phy code.
Signed-off-by: default avatarPeter Griffin <peter.griffin@linaro.org>
Acked-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20240404122559.898930-11-peter.griffin@linaro.orgSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent f2c6d0fa
...@@ -82,4 +82,5 @@ const struct samsung_ufs_phy_drvdata exynos7_ufs_phy = { ...@@ -82,4 +82,5 @@ const struct samsung_ufs_phy_drvdata exynos7_ufs_phy = {
.clk_list = exynos7_ufs_phy_clks, .clk_list = exynos7_ufs_phy_clks,
.num_clks = ARRAY_SIZE(exynos7_ufs_phy_clks), .num_clks = ARRAY_SIZE(exynos7_ufs_phy_clks),
.cdr_lock_status_offset = EXYNOS7_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS, .cdr_lock_status_offset = EXYNOS7_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
.wait_for_cdr = samsung_ufs_phy_wait_for_lock_acq,
}; };
...@@ -71,4 +71,5 @@ const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = { ...@@ -71,4 +71,5 @@ const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy = {
.clk_list = exynosautov9_ufs_phy_clks, .clk_list = exynosautov9_ufs_phy_clks,
.num_clks = ARRAY_SIZE(exynosautov9_ufs_phy_clks), .num_clks = ARRAY_SIZE(exynosautov9_ufs_phy_clks),
.cdr_lock_status_offset = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS, .cdr_lock_status_offset = EXYNOSAUTOV9_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
.wait_for_cdr = samsung_ufs_phy_wait_for_lock_acq,
}; };
...@@ -60,4 +60,5 @@ const struct samsung_ufs_phy_drvdata fsd_ufs_phy = { ...@@ -60,4 +60,5 @@ const struct samsung_ufs_phy_drvdata fsd_ufs_phy = {
.clk_list = fsd_ufs_phy_clks, .clk_list = fsd_ufs_phy_clks,
.num_clks = ARRAY_SIZE(fsd_ufs_phy_clks), .num_clks = ARRAY_SIZE(fsd_ufs_phy_clks),
.cdr_lock_status_offset = FSD_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS, .cdr_lock_status_offset = FSD_EMBEDDED_COMBO_PHY_CDR_LOCK_STATUS,
.wait_for_cdr = samsung_ufs_phy_wait_for_lock_acq,
}; };
...@@ -46,7 +46,7 @@ static void samsung_ufs_phy_config(struct samsung_ufs_phy *phy, ...@@ -46,7 +46,7 @@ static void samsung_ufs_phy_config(struct samsung_ufs_phy *phy,
} }
} }
static int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy) int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy, u8 lane)
{ {
struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy); struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
const unsigned int timeout_us = 100000; const unsigned int timeout_us = 100000;
...@@ -98,8 +98,15 @@ static int samsung_ufs_phy_calibrate(struct phy *phy) ...@@ -98,8 +98,15 @@ static int samsung_ufs_phy_calibrate(struct phy *phy)
} }
} }
if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS) for_each_phy_lane(ufs_phy, i) {
err = samsung_ufs_phy_wait_for_lock_acq(phy); if (ufs_phy->ufs_phy_state == CFG_PRE_INIT &&
ufs_phy->drvdata->wait_for_cal)
err = ufs_phy->drvdata->wait_for_cal(phy, i);
if (ufs_phy->ufs_phy_state == CFG_POST_PWR_HS &&
ufs_phy->drvdata->wait_for_cdr)
err = ufs_phy->drvdata->wait_for_cdr(phy, i);
}
/** /**
* In Samsung ufshci, PHY need to be calibrated at different * In Samsung ufshci, PHY need to be calibrated at different
......
...@@ -112,6 +112,9 @@ struct samsung_ufs_phy_drvdata { ...@@ -112,6 +112,9 @@ struct samsung_ufs_phy_drvdata {
const char * const *clk_list; const char * const *clk_list;
int num_clks; int num_clks;
u32 cdr_lock_status_offset; u32 cdr_lock_status_offset;
/* SoC's specific operations */
int (*wait_for_cal)(struct phy *phy, u8 lane);
int (*wait_for_cdr)(struct phy *phy, u8 lane);
}; };
struct samsung_ufs_phy { struct samsung_ufs_phy {
...@@ -139,6 +142,8 @@ static inline void samsung_ufs_phy_ctrl_isol( ...@@ -139,6 +142,8 @@ static inline void samsung_ufs_phy_ctrl_isol(
phy->isol.mask, isol ? 0 : phy->isol.en); phy->isol.mask, isol ? 0 : phy->isol.en);
} }
int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy, u8 lane);
extern const struct samsung_ufs_phy_drvdata exynos7_ufs_phy; extern const struct samsung_ufs_phy_drvdata exynos7_ufs_phy;
extern const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy; extern const struct samsung_ufs_phy_drvdata exynosautov9_ufs_phy;
extern const struct samsung_ufs_phy_drvdata fsd_ufs_phy; extern const struct samsung_ufs_phy_drvdata fsd_ufs_phy;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment