Re: [PATCH v4 3/3] phy: rockchip: phy-rockchip-inno-csidphy: add clock lane phase tuning
Michael Riesch <[email protected]> Mon, 3 Aug 2026 13:04:07 +0200
| Newsgroups | org.infradead.lists.linux-phy,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-rockchip,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Hi Gerald, On 7/25/26 18:56, Gerald Loacker wrote: > At high data rates like 4K60 (2500 Mbps), such as when using an > LT6911GXD bridge chip on an RK3588 board, fixed default timing parameters > can cause signal integrity issues and clock-data recovery failures. > The driver currently lacks a mechanism to adjust the clock lane sampling > phase to compensate for board-specific trace variations. > > Resolve this by parsing and applying the optional 'rockchip,clk-lane-phase' > device tree property. This enables board-specific tuning of the clock > lane sampling phase in ~40 ps steps (range 0-7) to optimize link > stability. If the property is absent, the driver falls back to the > hardware default. > > Signed-off-by: Gerald Loacker <[email protected]> Reviewed-by: Michael Riesch <[email protected]> Thanks and best regards, Michael > --- > drivers/phy/rockchip/phy-rockchip-inno-csidphy.c | 25 ++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c > index 5281f8dea0ad3..d989f1649b0e4 100644 > --- a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c > +++ b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c > @@ -69,6 +69,10 @@ > #define RK1808_CSIDPHY_CLK_CALIB_EN 0x168 > #define RK3568_CSIDPHY_CLK_CALIB_EN 0x168 > > +#define CSIDPHY_LANE_CLK_3_PHASE 0x38 > +#define CSIDPHY_CLK_PHASE_MASK GENMASK(6, 4) > +#define CSIDPHY_CLK_PHASE_DEFAULT 3 > + > #define RESETS_MAX 2 > > /* > @@ -151,6 +155,7 @@ struct rockchip_inno_csidphy { > const struct dphy_drv_data *drv_data; > struct phy_configure_opts_mipi_dphy config; > u8 hsfreq; > + int clk_phase; > }; > > static inline void write_grf_reg(struct rockchip_inno_csidphy *priv, > @@ -304,6 +309,13 @@ static int rockchip_inno_csidphy_power_on(struct phy *phy) > rockchip_inno_csidphy_ths_settle(priv, priv->hsfreq, > CSIDPHY_LANE_THS_SETTLE(i)); > > + if (priv->clk_phase >= 0) { > + val = readl(priv->phy_base + CSIDPHY_LANE_CLK_3_PHASE); > + val &= ~CSIDPHY_CLK_PHASE_MASK; > + val |= FIELD_PREP(CSIDPHY_CLK_PHASE_MASK, priv->clk_phase); > + writel(val, priv->phy_base + CSIDPHY_LANE_CLK_3_PHASE); > + } > + > write_grf_reg(priv, GRF_DPHY_CSIPHY_CLKLANE_EN, 0x1); > write_grf_reg(priv, GRF_DPHY_CSIPHY_DATALANE_EN, > GENMASK(priv->config.lanes - 1, 0)); > @@ -449,6 +461,7 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev) > struct device *dev = &pdev->dev; > struct phy_provider *phy_provider; > struct phy *phy; > + u32 phase; > int ret; > > priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > @@ -464,6 +477,18 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev) > return -ENODEV; > } > > + priv->clk_phase = -1; > + if (device_property_read_u32(dev, "rockchip,clk-lane-phase", > + &phase) == 0) { > + if (phase > 7) { > + dev_warn(dev, > + "invalid rockchip,clk-lane-phase %u, using default %u\n", > + phase, CSIDPHY_CLK_PHASE_DEFAULT); > + phase = CSIDPHY_CLK_PHASE_DEFAULT; > + } > + priv->clk_phase = phase; > + } > + > priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, > "rockchip,grf"); > if (IS_ERR(priv->grf)) { > -- linux-phy mailing list [email protected] https://lists.infradead.org/mailman/listinfo/linux-phy