diff --git a/drivers/phy/rockchip/phy-rockchip-mipi-rx.c b/drivers/phy/rockchip/phy-rockchip-mipi-rx.c index 47a037dd9bb2..c78c9e96c55f 100644 --- a/drivers/phy/rockchip/phy-rockchip-mipi-rx.c +++ b/drivers/phy/rockchip/phy-rockchip-mipi-rx.c @@ -48,6 +48,7 @@ #include #include #include +#include /* GRF */ #define RK1808_GRF_PD_VI_CON_OFFSET 0x0430 @@ -146,6 +147,17 @@ #define RK3326_CSI_DPHY_LANE3_WR_THS_SETTLE \ (RK3326_CSI_DPHY_LANE2_WR_THS_SETTLE + 0x80) +#define RK3326S_CSI_DPHY_CLK_WR_THS_SETTLE 0x160 +#define RK3326S_CSI_DPHY_LANE0_WR_THS_SETTLE \ + (RK3326S_CSI_DPHY_CLK_WR_THS_SETTLE + 0x80) +#define RK3326S_CSI_DPHY_LANE1_WR_THS_SETTLE \ + (RK3326S_CSI_DPHY_LANE0_WR_THS_SETTLE + 0x80) +#define RK3326S_CSI_DPHY_LANE2_WR_THS_SETTLE \ + (RK3326S_CSI_DPHY_LANE1_WR_THS_SETTLE + 0x80) +#define RK3326S_CSI_DPHY_LANE3_WR_THS_SETTLE \ + (RK3326S_CSI_DPHY_LANE2_WR_THS_SETTLE + 0x80) +#define RK3326S_CSI_DPHY_CLK_MODE 0x128 + #define RK3368_CSI_DPHY_CLK_WR_THS_SETTLE 0x100 #define RK3368_CSI_DPHY_LANE0_WR_THS_SETTLE \ (RK3368_CSI_DPHY_CLK_WR_THS_SETTLE + 0x80) @@ -218,6 +230,7 @@ enum mipi_dphy_chip_id { CHIP_ID_RK3368, CHIP_ID_RK3399, CHIP_ID_RK1126, + CHIP_ID_RK3326S, }; enum mipi_dphy_rx_pads { @@ -287,6 +300,7 @@ enum csiphy_reg_id { //rv1126 only CSIPHY_MIPI_LVDS_MODEL, CSIPHY_LVDS_MODE, + CSIPHY_CLK_MODE, }; enum mipi_dphy_ctl_type { @@ -473,6 +487,23 @@ static const struct csiphy_reg rk3326_csiphy_regs[] = { [CSIPHY_LANE3_CALIB_ENABLE] = CSIPHY_REG(RK3326_CSI_DPHY_LANE3_CALIB_EN), }; +static const struct csiphy_reg rk3326s_csiphy_regs[] = { + [CSIPHY_CTRL_LANE_ENABLE] = CSIPHY_REG(RK3326_CSI_DPHY_CTRL_LANE_ENABLE), + [CSIPHY_CTRL_PWRCTL] = CSIPHY_REG(RK3326_CSI_DPHY_CTRL_PWRCTL), + [CSIPHY_CTRL_DIG_RST] = CSIPHY_REG(RK3326_CSI_DPHY_CTRL_DIG_RST), + [CSIPHY_CLK_THS_SETTLE] = CSIPHY_REG(RK3326S_CSI_DPHY_CLK_WR_THS_SETTLE), + [CSIPHY_LANE0_THS_SETTLE] = CSIPHY_REG(RK3326S_CSI_DPHY_LANE0_WR_THS_SETTLE), + [CSIPHY_LANE1_THS_SETTLE] = CSIPHY_REG(RK3326S_CSI_DPHY_LANE1_WR_THS_SETTLE), + [CSIPHY_LANE2_THS_SETTLE] = CSIPHY_REG(RK3326S_CSI_DPHY_LANE2_WR_THS_SETTLE), + [CSIPHY_LANE3_THS_SETTLE] = CSIPHY_REG(RK3326S_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), + [CSIPHY_CLK_MODE] = CSIPHY_REG(RK3326S_CSI_DPHY_CLK_MODE), +}; + static const struct csiphy_reg rk3368_csiphy_regs[] = { [CSIPHY_CTRL_LANE_ENABLE] = CSIPHY_REG(RK3368_CSI_DPHY_CTRL_LANE_ENABLE), [CSIPHY_CTRL_PWRCTL] = CSIPHY_REG(RK3368_CSI_DPHY_CTRL_PWRCTL), @@ -1011,6 +1042,12 @@ static const struct hsfreq_range rk3326_mipidphy_hsfreq_ranges[] = { {1249, 0x0c}, {1349, 0x0d}, {1500, 0x0e} }; +static const struct hsfreq_range rk3326s_mipidphy_hsfreq_ranges[] = { + { 109, 0x02}, { 149, 0x03}, { 199, 0x06}, { 249, 0x06}, + { 299, 0x06}, { 399, 0x08}, { 499, 0x0b}, { 599, 0x0e}, + { 699, 0x10}, { 799, 0x12}, { 999, 0x16}, {1199, 0x1e}, +}; + static const struct hsfreq_range rk3368_mipidphy_hsfreq_ranges[] = { { 109, 0x00}, { 149, 0x01}, { 199, 0x02}, { 249, 0x03}, { 299, 0x04}, { 399, 0x05}, { 499, 0x06}, { 599, 0x07}, @@ -1325,6 +1362,7 @@ static int csi_mipidphy_stream_on(struct mipidphy_priv *priv, int num_hsfreq_ranges = drv_data->num_hsfreq_ranges; int i, hsfreq = 0; u32 val = 0; + u32 clk_mode = 0x03; write_grf_reg(priv, GRF_DVP_V18SEL, 0x1); @@ -1344,6 +1382,13 @@ static int csi_mipidphy_stream_on(struct mipidphy_priv *priv, /* Reset dphy digital part */ write_csiphy_reg(priv, CSIPHY_CTRL_DIG_RST, 0x1e); write_csiphy_reg(priv, CSIPHY_CTRL_DIG_RST, 0x1f); + if (drv_data->chip_id == CHIP_ID_RK3326S) { + if (sensor->mbus.flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) + clk_mode = 0x03; + else if (sensor->mbus.flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK) + clk_mode = 0; + write_csiphy_reg(priv, CSIPHY_CLK_MODE, clk_mode); + } } else { /* Disable MIPI internal logical and switch to LVDS bank */ write_csiphy_reg(priv, CSIPHY_CTRL_DIG_RST, 0x3e); @@ -1467,6 +1512,18 @@ static const struct dphy_drv_data rk3326_mipidphy_drv_data = { .chip_id = CHIP_ID_RK3326, }; +static const struct dphy_drv_data rk3326s_mipidphy_drv_data = { + .clks = rk3326_mipidphy_clks, + .num_clks = ARRAY_SIZE(rk3326_mipidphy_clks), + .hsfreq_ranges = rk3326s_mipidphy_hsfreq_ranges, + .num_hsfreq_ranges = ARRAY_SIZE(rk3326s_mipidphy_hsfreq_ranges), + .grf_regs = rk3326_grf_dphy_regs, + .csiphy_regs = rk3326s_csiphy_regs, + .ctl_type = MIPI_DPHY_CTL_CSI_HOST, + .individual_init = default_mipidphy_individual_init, + .chip_id = CHIP_ID_RK3326S, +}; + static const struct dphy_drv_data rk3368_mipidphy_drv_data = { .clks = rk3368_mipidphy_clks, .num_clks = ARRAY_SIZE(rk3368_mipidphy_clks), @@ -1515,6 +1572,10 @@ static const struct of_device_id rockchip_mipidphy_match_id[] = { .compatible = "rockchip,rk3326-mipi-dphy", .data = &rk3326_mipidphy_drv_data, }, + { + .compatible = "rockchip,rk3326s-mipi-dphy", + .data = &rk3326s_mipidphy_drv_data, + }, { .compatible = "rockchip,rk3368-mipi-dphy", .data = &rk3368_mipidphy_drv_data, @@ -1718,6 +1779,9 @@ static int rockchip_mipidphy_probe(struct platform_device *pdev) priv->phy_index = 0; drv_data = of_id->data; + if (soc_is_px30s()) + drv_data = &rk3326s_mipidphy_drv_data; + for (i = 0; i < drv_data->num_clks; i++) { priv->clks[i] = devm_clk_get(dev, drv_data->clks[i]);