From c58eca71736c02f6ae9386ac2fcd530ace8ef822 Mon Sep 17 00:00:00 2001 From: Wenlong Zhuang Date: Mon, 5 Nov 2018 11:19:36 +0800 Subject: [PATCH] phy: rockchip: mipi-rx: add dphy calibration for ultra high clock frequency RK1808 MIPI CSI DPHY support 2 Gbps maximum data transfer rate per lane. Enable calibration reception if data rate is bigger than 1.5 Gbps. Change-Id: Iec2088ac74f8f9599de96d5b8ad5dd986665ce0e Signed-off-by: Wenlong Zhuang --- drivers/phy/rockchip/phy-rockchip-mipi-rx.c | 48 ++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-mipi-rx.c b/drivers/phy/rockchip/phy-rockchip-mipi-rx.c index 937b3544cfe4..eab431ed4ceb 100644 --- a/drivers/phy/rockchip/phy-rockchip-mipi-rx.c +++ b/drivers/phy/rockchip/phy-rockchip-mipi-rx.c @@ -122,6 +122,24 @@ #define RK3326_CSI_DPHY_LANE3_WR_THS_SETTLE \ (RK3326_CSI_DPHY_LANE2_WR_THS_SETTLE + 0x80) +/* Calibration reception enable */ +#define RK1808_CSI_DPHY_CLK_CALIB_EN 0x168 +#define RK1808_CSI_DPHY_LANE0_CALIB_EN 0x1e8 +#define RK1808_CSI_DPHY_LANE1_CALIB_EN 0x268 +#define RK1808_CSI_DPHY_LANE2_CALIB_EN 0x2e8 +#define RK1808_CSI_DPHY_LANE3_CALIB_EN 0x368 + +#define RK3326_CSI_DPHY_CLK_CALIB_EN \ + MIPI_CSI_DPHY_CTRL_INVALID_OFFSET +#define RK3326_CSI_DPHY_LANE0_CALIB_EN \ + MIPI_CSI_DPHY_CTRL_INVALID_OFFSET +#define RK3326_CSI_DPHY_LANE1_CALIB_EN \ + MIPI_CSI_DPHY_CTRL_INVALID_OFFSET +#define RK3326_CSI_DPHY_LANE2_CALIB_EN \ + MIPI_CSI_DPHY_CTRL_INVALID_OFFSET +#define RK3326_CSI_DPHY_LANE3_CALIB_EN \ + MIPI_CSI_DPHY_CTRL_INVALID_OFFSET + /* * CSI HOST */ @@ -187,7 +205,12 @@ enum csiphy_reg_id { CSIPHY_LANE0_THS_SETTLE, CSIPHY_LANE1_THS_SETTLE, CSIPHY_LANE2_THS_SETTLE, - CSIPHY_LANE3_THS_SETTLE + CSIPHY_LANE3_THS_SETTLE, + CSIPHY_CLK_CALIB_ENABLE, + CSIPHY_LANE0_CALIB_ENABLE, + CSIPHY_LANE1_CALIB_ENABLE, + CSIPHY_LANE2_CALIB_ENABLE, + CSIPHY_LANE3_CALIB_ENABLE, }; enum mipi_dphy_ctl_type { @@ -328,6 +351,11 @@ static const struct csiphy_reg rk1808_csiphy_regs[] = { [CSIPHY_LANE1_THS_SETTLE] = CSIPHY_REG(RK1808_CSI_DPHY_LANE1_WR_THS_SETTLE), [CSIPHY_LANE2_THS_SETTLE] = CSIPHY_REG(RK1808_CSI_DPHY_LANE2_WR_THS_SETTLE), [CSIPHY_LANE3_THS_SETTLE] = CSIPHY_REG(RK1808_CSI_DPHY_LANE3_WR_THS_SETTLE), + [CSIPHY_CLK_CALIB_ENABLE] = CSIPHY_REG(RK1808_CSI_DPHY_CLK_CALIB_EN), + [CSIPHY_LANE0_CALIB_ENABLE] = CSIPHY_REG(RK1808_CSI_DPHY_LANE0_CALIB_EN), + [CSIPHY_LANE1_CALIB_ENABLE] = CSIPHY_REG(RK1808_CSI_DPHY_LANE1_CALIB_EN), + [CSIPHY_LANE2_CALIB_ENABLE] = CSIPHY_REG(RK1808_CSI_DPHY_LANE2_CALIB_EN), + [CSIPHY_LANE3_CALIB_ENABLE] = CSIPHY_REG(RK1808_CSI_DPHY_LANE3_CALIB_EN), }; static const struct csiphy_reg rk3326_csiphy_regs[] = { @@ -339,6 +367,11 @@ static const struct csiphy_reg rk3326_csiphy_regs[] = { [CSIPHY_LANE1_THS_SETTLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE1_WR_THS_SETTLE), [CSIPHY_LANE2_THS_SETTLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE2_WR_THS_SETTLE), [CSIPHY_LANE3_THS_SETTLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE3_WR_THS_SETTLE), + [CSIPHY_CLK_CALIB_ENABLE] = CSIPHY_REG(RK3326_CSI_DPHY_CLK_CALIB_EN), + [CSIPHY_LANE0_CALIB_ENABLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE0_CALIB_EN), + [CSIPHY_LANE1_CALIB_ENABLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE1_CALIB_EN), + [CSIPHY_LANE2_CALIB_ENABLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE2_CALIB_EN), + [CSIPHY_LANE3_CALIB_ENABLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE3_CALIB_EN), }; struct hsfreq_range { @@ -996,6 +1029,19 @@ static int csi_mipidphy_stream_on(struct mipidphy_priv *priv, /* not into receive mode/wait stopstate */ write_grf_reg(priv, GRF_DPHY_CSIPHY_FORCERXMODE, 0x0); + /* enable calibration */ + if (priv->data_rate_mbps > 1500) { + write_csiphy_reg(priv, CSIPHY_CLK_CALIB_ENABLE, 0x80); + if (sensor->lanes > 0x00) + write_csiphy_reg(priv, CSIPHY_LANE0_CALIB_ENABLE, 0x80); + if (sensor->lanes > 0x01) + write_csiphy_reg(priv, CSIPHY_LANE1_CALIB_ENABLE, 0x80); + if (sensor->lanes > 0x02) + write_csiphy_reg(priv, CSIPHY_LANE2_CALIB_ENABLE, 0x80); + if (sensor->lanes > 0x03) + write_csiphy_reg(priv, CSIPHY_LANE3_CALIB_ENABLE, 0x80); + } + /* set clock lane and data lane */ for (i = 0; i < num_hsfreq_ranges; i++) { if (hsfreq_ranges[i].range_h >= priv->data_rate_mbps) {