2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

phy: mediatek: tphy: Cleanup and document slew calibration

While it's true that, generally, the T-PHY V3 does not support the
slew calibration process, some minor versions of it actually do,
moreover, some SoCs may not support this even though the version
of the PHY IP does.

The reference clock and rate coefficient parameters are used only
for slew calibration: move those to platform data, then document
and change the checks in hs_slew_rate_calibrate() to perform the
calibration only if:
 - EYE value was not supplied (pre-calculated calibration); and
 - Slew reference clock value is present (not zero); and
 - Slew coefficient is present (not zero).

Moreover, change the probe function to always check if both the
slew reference clock and coefficient properties are present and,
if not, assign the value from platform data (which, as reminder,
if not added means that it's zero!), instead of checking the PHY
IP version.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://lore.kernel.org/r/20250623120315.109881-3-angelogioacchino.delregno@collabora.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
AngeloGioacchino Del Regno 2025-06-23 14:03:15 +02:00 committed by Vinod Koul
parent 9cc82c2498
commit d6306fc5d7

View File

@ -210,8 +210,6 @@
#define P2F_USB_FM_VALID BIT(0) #define P2F_USB_FM_VALID BIT(0)
#define P2F_RG_FRCK_EN BIT(8) #define P2F_RG_FRCK_EN BIT(8)
#define U3P_REF_CLK 26 /* MHZ */
#define U3P_SLEW_RATE_COEF 28
#define U3P_SR_COEF_DIVISOR 1000 #define U3P_SR_COEF_DIVISOR 1000
#define U3P_FM_DET_CYCLE_CNT 1024 #define U3P_FM_DET_CYCLE_CNT 1024
@ -285,12 +283,16 @@ enum mtk_phy_version {
* @sw_efuse_supported: Switches off eFuse auto-load from PHY and applies values * @sw_efuse_supported: Switches off eFuse auto-load from PHY and applies values
* read from different nvmem (usually different eFuse array) * read from different nvmem (usually different eFuse array)
* that is pointed at in the device tree node for this PHY * that is pointed at in the device tree node for this PHY
* @slew_ref_clk_mhz: Default reference clock (in MHz) for slew rate calibration
* @slew_rate_coefficient: Coefficient for slew rate calibration
* @version: PHY IP Version * @version: PHY IP Version
*/ */
struct mtk_phy_pdata { struct mtk_phy_pdata {
bool avoid_rx_sen_degradation; bool avoid_rx_sen_degradation;
bool sw_pll_48m_to_26m; bool sw_pll_48m_to_26m;
bool sw_efuse_supported; bool sw_efuse_supported;
u8 slew_ref_clock_mhz;
u8 slew_rate_coefficient;
enum mtk_phy_version version; enum mtk_phy_version version;
}; };
@ -686,12 +688,14 @@ static void hs_slew_rate_calibrate(struct mtk_tphy *tphy,
int fm_out; int fm_out;
u32 tmp; u32 tmp;
/* HW V3 doesn't support slew rate cal anymore */ /*
if (tphy->pdata->version == MTK_PHY_V3) * If a fixed HS slew rate (EYE) value was supplied, don't run the
return; * calibration sequence and prefer using that value instead; also,
* if there is no reference clock for slew calibration or there is
/* use force value */ * no slew coefficient, this means that the slew rate calibration
if (instance->eye_src) * sequence is not supported.
*/
if (instance->eye_src || !tphy->src_ref_clk || !tphy->src_coef)
return; return;
/* enable USB ring oscillator */ /* enable USB ring oscillator */
@ -1516,12 +1520,16 @@ static const struct phy_ops mtk_tphy_ops = {
static const struct mtk_phy_pdata tphy_v1_pdata = { static const struct mtk_phy_pdata tphy_v1_pdata = {
.avoid_rx_sen_degradation = false, .avoid_rx_sen_degradation = false,
.slew_ref_clock_mhz = 26,
.slew_rate_coefficient = 28,
.version = MTK_PHY_V1, .version = MTK_PHY_V1,
}; };
static const struct mtk_phy_pdata tphy_v2_pdata = { static const struct mtk_phy_pdata tphy_v2_pdata = {
.avoid_rx_sen_degradation = false, .avoid_rx_sen_degradation = false,
.sw_efuse_supported = true, .sw_efuse_supported = true,
.slew_ref_clock_mhz = 26,
.slew_rate_coefficient = 28,
.version = MTK_PHY_V2, .version = MTK_PHY_V2,
}; };
@ -1532,6 +1540,8 @@ static const struct mtk_phy_pdata tphy_v3_pdata = {
static const struct mtk_phy_pdata mt8173_pdata = { static const struct mtk_phy_pdata mt8173_pdata = {
.avoid_rx_sen_degradation = true, .avoid_rx_sen_degradation = true,
.slew_ref_clock_mhz = 26,
.slew_rate_coefficient = 28,
.version = MTK_PHY_V1, .version = MTK_PHY_V1,
}; };
@ -1561,7 +1571,7 @@ static int mtk_tphy_probe(struct platform_device *pdev)
struct resource *sif_res; struct resource *sif_res;
struct mtk_tphy *tphy; struct mtk_tphy *tphy;
struct resource res; struct resource res;
int port; int port, ret;
tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL); tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL);
if (!tphy) if (!tphy)
@ -1591,15 +1601,14 @@ static int mtk_tphy_probe(struct platform_device *pdev)
} }
} }
if (tphy->pdata->version < MTK_PHY_V3) { /* Optional properties for slew calibration variation */
tphy->src_ref_clk = U3P_REF_CLK; ret = device_property_read_u32(dev, "mediatek,src-ref-clk-mhz", &tphy->src_ref_clk);
tphy->src_coef = U3P_SLEW_RATE_COEF; if (ret)
/* update parameters of slew rate calibrate if exist */ tphy->src_ref_clk = tphy->pdata->slew_ref_clock_mhz;
device_property_read_u32(dev, "mediatek,src-ref-clk-mhz",
&tphy->src_ref_clk); ret = device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef);
device_property_read_u32(dev, "mediatek,src-coef", if (ret)
&tphy->src_coef); tphy->src_coef = tphy->pdata->slew_rate_coefficient;
}
port = 0; port = 0;
for_each_child_of_node_scoped(np, child_np) { for_each_child_of_node_scoped(np, child_np) {