mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 12:13:51 -04:00
phy: rockchip: phy-rockchip-inno-csidphy: add clock lane phase tuning
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 <gerald.loacker@wolfvision.net> Reviewed-by: Michael Riesch <michael.riesch@collabora.com> Link: https://patch.msgid.link/20260725-feature-mipi-csi-dphy-4k60-v4-3-5b2c4626d31e@wolfvision.net Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
committed by
Vinod Koul
parent
f82ff8609f
commit
333c23c316
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user