summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/phy/rockchip/phy-rockchip-inno-csidphy.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c
index 5281f8dea0ad..d989f1649b0e 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)) {