From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 140 insertions(+), 11 deletions(-) diff --git a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c index e0a9fd6..4aada19 100644 --- a/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c +++ b/kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy-hw.c @@ -54,6 +54,7 @@ #define CSI2_DPHY_DUAL_CAL_EN (0x80) #define CSI2_DPHY_CLK_INV (0X84) +#define CSI2_DPHY_CLK_CONTINUE_MODE (0x128) #define CSI2_DPHY_CLK_WR_THS_SETTLE (0x160) #define CSI2_DPHY_CLK_CALIB_EN (0x168) #define CSI2_DPHY_LANE0_WR_THS_SETTLE (0x1e0) @@ -64,6 +65,7 @@ #define CSI2_DPHY_LANE2_CALIB_EN (0x2e8) #define CSI2_DPHY_LANE3_WR_THS_SETTLE (0x360) #define CSI2_DPHY_LANE3_CALIB_EN (0x368) +#define CSI2_DPHY_CLK1_CONTINUE_MODE (0x3a8) #define CSI2_DPHY_CLK1_WR_THS_SETTLE (0x3e0) #define CSI2_DPHY_CLK1_CALIB_EN (0x3e8) @@ -213,6 +215,8 @@ CSI2PHY_PATH1_MODEL, CSI2PHY_PATH1_LVDS_MODEL, CSI2PHY_CLK_INV, + CSI2PHY_CLK_CONTINUE_MODE, + CSI2PHY_CLK1_CONTINUE_MODE, }; #define HIWORD_UPDATE(val, mask, shift) \ @@ -232,9 +236,14 @@ static inline void write_sys_grf_reg(struct csi2_dphy_hw *hw, int index, u8 value) { - const struct grf_reg *reg = &hw->grf_regs[index]; - unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift); + const struct grf_reg *reg = NULL; + unsigned int val = 0; + if (index >= hw->drv_data->num_grf_regs) + return; + + reg = &hw->grf_regs[index]; + val = HIWORD_UPDATE(value, reg->mask, reg->shift); if (reg->mask) regmap_write(hw->regmap_sys_grf, reg->offset, val); } @@ -242,18 +251,27 @@ static inline void write_grf_reg(struct csi2_dphy_hw *hw, int index, u8 value) { - const struct grf_reg *reg = &hw->grf_regs[index]; - unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift); + const struct grf_reg *reg = NULL; + unsigned int val = 0; + if (index >= hw->drv_data->num_grf_regs) + return; + + reg = &hw->grf_regs[index]; + val = HIWORD_UPDATE(value, reg->mask, reg->shift); if (reg->mask) regmap_write(hw->regmap_grf, reg->offset, val); } static inline u32 read_grf_reg(struct csi2_dphy_hw *hw, int index) { - const struct grf_reg *reg = &hw->grf_regs[index]; + const struct grf_reg *reg = NULL; unsigned int val = 0; + if (index >= hw->drv_data->num_grf_regs) + return -EINVAL; + + reg = &hw->grf_regs[index]; if (reg->mask) { regmap_read(hw->regmap_grf, reg->offset, &val); val = (val >> reg->shift) & reg->mask; @@ -265,8 +283,12 @@ static inline void write_csi2_dphy_reg(struct csi2_dphy_hw *hw, int index, u32 value) { - const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index]; + const struct csi2dphy_reg *reg = NULL; + if (index >= hw->drv_data->num_csi2dphy_regs) + return; + + reg = &hw->csi2dphy_regs[index]; if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) || (index == CSI2PHY_CLK_LANE_ENABLE) || (index != CSI2PHY_REG_CTRL_LANE_ENABLE && @@ -277,9 +299,13 @@ static inline void write_csi2_dphy_reg_mask(struct csi2_dphy_hw *hw, int index, u32 value, u32 mask) { - const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index]; + const struct csi2dphy_reg *reg = NULL; u32 read_val = 0; + if (index >= hw->drv_data->num_csi2dphy_regs) + return; + + reg = &hw->csi2dphy_regs[index]; read_val = readl(hw->hw_base_addr + reg->offset); read_val &= ~mask; read_val |= value; @@ -289,8 +315,12 @@ static inline void read_csi2_dphy_reg(struct csi2_dphy_hw *hw, int index, u32 *value) { - const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index]; + const struct csi2dphy_reg *reg = NULL; + if (index >= hw->drv_data->num_csi2dphy_regs) + return; + + reg = &hw->csi2dphy_regs[index]; if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) || (index == CSI2PHY_CLK_LANE_ENABLE) || (index != CSI2PHY_REG_CTRL_LANE_ENABLE && @@ -397,6 +427,8 @@ [CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE), [CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN), [CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN), + [CSI2PHY_CLK_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK_CONTINUE_MODE), + [CSI2PHY_CLK1_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CONTINUE_MODE), }; static const struct grf_reg rv1106_grf_dphy_regs[] = { @@ -709,19 +741,30 @@ val |= (GENMASK(sensor->lanes - 1, 0) << CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) | (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); + if (sensor->mbus.flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) + write_csi2_dphy_reg(hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30); } else { if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT))) val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); - if (dphy->phy_index % 3 == DPHY1) + if (dphy->phy_index % 3 == DPHY1) { val |= (GENMASK(sensor->lanes - 1, 0) << CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT); + if (sensor->mbus.flags & + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) + write_csi2_dphy_reg( + hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30); + } if (dphy->phy_index % 3 == DPHY2) { val |= (GENMASK(sensor->lanes - 1, 0) << CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT); if (hw->drv_data->chip_id >= CHIP_ID_RK3588) write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6)); + if (sensor->mbus.flags & + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) + write_csi2_dphy_reg( + hw, CSI2PHY_CLK1_CONTINUE_MODE, 0x30); } } val |= pre_val; @@ -859,10 +902,87 @@ write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01); csi2_dphy_hw_do_reset(hw); - usleep_range(500, 1000); mutex_unlock(&hw->mutex); + return 0; +} + +static int csi2_dphy_hw_quick_stream_on(struct csi2_dphy *dphy, + struct v4l2_subdev *sd) +{ + struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); + struct csi2_sensor *sensor; + struct csi2_dphy_hw *hw = dphy->dphy_hw; + u32 val = 0, pre_val = 0; + + if (!sensor_sd) + return -ENODEV; + sensor = sd_to_sensor(dphy, sensor_sd); + if (!sensor) + return -ENODEV; + + read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val); + if (hw->lane_mode == LANE_MODE_FULL) { + val |= (GENMASK(sensor->lanes - 1, 0) << + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) | + (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); + } else { + if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT))) + val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); + + if (dphy->phy_index % 3 == DPHY1) + val |= (GENMASK(sensor->lanes - 1, 0) << + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT); + + if (dphy->phy_index % 3 == DPHY2) { + val |= (GENMASK(sensor->lanes - 1, 0) << + CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT); + if (hw->drv_data->chip_id >= CHIP_ID_RK3588) + write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6)); + } + } + pre_val |= val; + write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val); + return 0; +} + +static int csi2_dphy_hw_quick_stream_off(struct csi2_dphy *dphy, + struct v4l2_subdev *sd) +{ + struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); + struct csi2_sensor *sensor; + struct csi2_dphy_hw *hw = dphy->dphy_hw; + u32 val = 0, pre_val = 0; + + if (!sensor_sd) + return -ENODEV; + sensor = sd_to_sensor(dphy, sensor_sd); + if (!sensor) + return -ENODEV; + + read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val); + if (hw->lane_mode == LANE_MODE_FULL) { + val |= (GENMASK(sensor->lanes - 1, 0) << + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) | + (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); + } else { + if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT))) + val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); + + if (dphy->phy_index % 3 == DPHY1) + val |= (GENMASK(sensor->lanes - 1, 0) << + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT); + + if (dphy->phy_index % 3 == DPHY2) { + val |= (GENMASK(sensor->lanes - 1, 0) << + CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT); + if (hw->drv_data->chip_id >= CHIP_ID_RK3588) + write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6)); + } + } + pre_val &= ~val; + write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val); return 0; } @@ -913,7 +1033,9 @@ .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), .csi2dphy_regs = rk3568_csi2dphy_regs, + .num_csi2dphy_regs = ARRAY_SIZE(rk3568_csi2dphy_regs), .grf_regs = rk3568_grf_dphy_regs, + .num_grf_regs = ARRAY_SIZE(rk3568_grf_dphy_regs), .individual_init = rk3568_csi2_dphy_hw_individual_init, .chip_id = CHIP_ID_RK3568, .stream_on = csi2_dphy_hw_stream_on, @@ -924,7 +1046,9 @@ .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), .csi2dphy_regs = rk3588_csi2dphy_regs, + .num_csi2dphy_regs = ARRAY_SIZE(rk3588_csi2dphy_regs), .grf_regs = rk3588_grf_dphy_regs, + .num_grf_regs = ARRAY_SIZE(rk3588_grf_dphy_regs), .individual_init = rk3588_csi2_dphy_hw_individual_init, .chip_id = CHIP_ID_RK3588, .stream_on = csi2_dphy_hw_stream_on, @@ -935,7 +1059,9 @@ .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), .csi2dphy_regs = rv1106_csi2dphy_regs, + .num_csi2dphy_regs = ARRAY_SIZE(rv1106_csi2dphy_regs), .grf_regs = rv1106_grf_dphy_regs, + .num_grf_regs = ARRAY_SIZE(rv1106_grf_dphy_regs), .individual_init = rv1106_csi2_dphy_hw_individual_init, .chip_id = CHIP_ID_RV1106, .stream_on = csi2_dphy_hw_stream_on, @@ -946,7 +1072,9 @@ .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), .csi2dphy_regs = rk3562_csi2dphy_regs, + .num_csi2dphy_regs = ARRAY_SIZE(rk3562_csi2dphy_regs), .grf_regs = rk3562_grf_dphy_regs, + .num_grf_regs = ARRAY_SIZE(rk3562_grf_dphy_regs), .individual_init = rk3562_csi2_dphy_hw_individual_init, .chip_id = CHIP_ID_RK3562, .stream_on = csi2_dphy_hw_stream_on, @@ -1024,7 +1152,6 @@ dphy_hw->drv_data = drv_data; dphy_hw->lane_mode = LANE_MODE_UNDEF; dphy_hw->grf_regs = drv_data->grf_regs; - dphy_hw->txrx_regs = drv_data->txrx_regs; dphy_hw->csi2dphy_regs = drv_data->csi2dphy_regs; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1041,6 +1168,8 @@ } dphy_hw->stream_on = drv_data->stream_on; dphy_hw->stream_off = drv_data->stream_off; + dphy_hw->quick_stream_on = csi2_dphy_hw_quick_stream_on; + dphy_hw->quick_stream_off = csi2_dphy_hw_quick_stream_off; if (drv_data->chip_id == CHIP_ID_RV1106) { dphy_hw->ttl_mode_enable = csi2_dphy_hw_ttl_mode_enable; -- Gitblit v1.6.2