Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

AngeloGioacchino Del Regno and committed by
Vinod Koul
d6306fc5 9cc82c24

+27 -18
+27 -18
drivers/phy/mediatek/phy-mtk-tphy.c
··· 210 210 #define P2F_USB_FM_VALID BIT(0) 211 211 #define P2F_RG_FRCK_EN BIT(8) 212 212 213 - #define U3P_REF_CLK 26 /* MHZ */ 214 - #define U3P_SLEW_RATE_COEF 28 215 213 #define U3P_SR_COEF_DIVISOR 1000 216 214 #define U3P_FM_DET_CYCLE_CNT 1024 217 215 ··· 283 285 * @sw_efuse_supported: Switches off eFuse auto-load from PHY and applies values 284 286 * read from different nvmem (usually different eFuse array) 285 287 * that is pointed at in the device tree node for this PHY 288 + * @slew_ref_clk_mhz: Default reference clock (in MHz) for slew rate calibration 289 + * @slew_rate_coefficient: Coefficient for slew rate calibration 286 290 * @version: PHY IP Version 287 291 */ 288 292 struct mtk_phy_pdata { 289 293 bool avoid_rx_sen_degradation; 290 294 bool sw_pll_48m_to_26m; 291 295 bool sw_efuse_supported; 296 + u8 slew_ref_clock_mhz; 297 + u8 slew_rate_coefficient; 292 298 enum mtk_phy_version version; 293 299 }; 294 300 ··· 688 686 int fm_out; 689 687 u32 tmp; 690 688 691 - /* HW V3 doesn't support slew rate cal anymore */ 692 - if (tphy->pdata->version == MTK_PHY_V3) 693 - return; 694 - 695 - /* use force value */ 696 - if (instance->eye_src) 689 + /* 690 + * If a fixed HS slew rate (EYE) value was supplied, don't run the 691 + * calibration sequence and prefer using that value instead; also, 692 + * if there is no reference clock for slew calibration or there is 693 + * no slew coefficient, this means that the slew rate calibration 694 + * sequence is not supported. 695 + */ 696 + if (instance->eye_src || !tphy->src_ref_clk || !tphy->src_coef) 697 697 return; 698 698 699 699 /* enable USB ring oscillator */ ··· 1520 1516 1521 1517 static const struct mtk_phy_pdata tphy_v1_pdata = { 1522 1518 .avoid_rx_sen_degradation = false, 1519 + .slew_ref_clock_mhz = 26, 1520 + .slew_rate_coefficient = 28, 1523 1521 .version = MTK_PHY_V1, 1524 1522 }; 1525 1523 1526 1524 static const struct mtk_phy_pdata tphy_v2_pdata = { 1527 1525 .avoid_rx_sen_degradation = false, 1528 1526 .sw_efuse_supported = true, 1527 + .slew_ref_clock_mhz = 26, 1528 + .slew_rate_coefficient = 28, 1529 1529 .version = MTK_PHY_V2, 1530 1530 }; 1531 1531 ··· 1540 1532 1541 1533 static const struct mtk_phy_pdata mt8173_pdata = { 1542 1534 .avoid_rx_sen_degradation = true, 1535 + .slew_ref_clock_mhz = 26, 1536 + .slew_rate_coefficient = 28, 1543 1537 .version = MTK_PHY_V1, 1544 1538 }; 1545 1539 ··· 1571 1561 struct resource *sif_res; 1572 1562 struct mtk_tphy *tphy; 1573 1563 struct resource res; 1574 - int port; 1564 + int port, ret; 1575 1565 1576 1566 tphy = devm_kzalloc(dev, sizeof(*tphy), GFP_KERNEL); 1577 1567 if (!tphy) ··· 1601 1591 } 1602 1592 } 1603 1593 1604 - if (tphy->pdata->version < MTK_PHY_V3) { 1605 - tphy->src_ref_clk = U3P_REF_CLK; 1606 - tphy->src_coef = U3P_SLEW_RATE_COEF; 1607 - /* update parameters of slew rate calibrate if exist */ 1608 - device_property_read_u32(dev, "mediatek,src-ref-clk-mhz", 1609 - &tphy->src_ref_clk); 1610 - device_property_read_u32(dev, "mediatek,src-coef", 1611 - &tphy->src_coef); 1612 - } 1594 + /* Optional properties for slew calibration variation */ 1595 + ret = device_property_read_u32(dev, "mediatek,src-ref-clk-mhz", &tphy->src_ref_clk); 1596 + if (ret) 1597 + tphy->src_ref_clk = tphy->pdata->slew_ref_clock_mhz; 1598 + 1599 + ret = device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef); 1600 + if (ret) 1601 + tphy->src_coef = tphy->pdata->slew_rate_coefficient; 1613 1602 1614 1603 port = 0; 1615 1604 for_each_child_of_node_scoped(np, child_np) {