.. | .. |
---|
54 | 54 | #define CSI2_DPHY_DUAL_CAL_EN (0x80) |
---|
55 | 55 | #define CSI2_DPHY_CLK_INV (0X84) |
---|
56 | 56 | |
---|
| 57 | +#define CSI2_DPHY_CLK_CONTINUE_MODE (0x128) |
---|
57 | 58 | #define CSI2_DPHY_CLK_WR_THS_SETTLE (0x160) |
---|
58 | 59 | #define CSI2_DPHY_CLK_CALIB_EN (0x168) |
---|
59 | 60 | #define CSI2_DPHY_LANE0_WR_THS_SETTLE (0x1e0) |
---|
.. | .. |
---|
64 | 65 | #define CSI2_DPHY_LANE2_CALIB_EN (0x2e8) |
---|
65 | 66 | #define CSI2_DPHY_LANE3_WR_THS_SETTLE (0x360) |
---|
66 | 67 | #define CSI2_DPHY_LANE3_CALIB_EN (0x368) |
---|
| 68 | +#define CSI2_DPHY_CLK1_CONTINUE_MODE (0x3a8) |
---|
67 | 69 | #define CSI2_DPHY_CLK1_WR_THS_SETTLE (0x3e0) |
---|
68 | 70 | #define CSI2_DPHY_CLK1_CALIB_EN (0x3e8) |
---|
69 | 71 | |
---|
.. | .. |
---|
213 | 215 | CSI2PHY_PATH1_MODEL, |
---|
214 | 216 | CSI2PHY_PATH1_LVDS_MODEL, |
---|
215 | 217 | CSI2PHY_CLK_INV, |
---|
| 218 | + CSI2PHY_CLK_CONTINUE_MODE, |
---|
| 219 | + CSI2PHY_CLK1_CONTINUE_MODE, |
---|
216 | 220 | }; |
---|
217 | 221 | |
---|
218 | 222 | #define HIWORD_UPDATE(val, mask, shift) \ |
---|
.. | .. |
---|
232 | 236 | static inline void write_sys_grf_reg(struct csi2_dphy_hw *hw, |
---|
233 | 237 | int index, u8 value) |
---|
234 | 238 | { |
---|
235 | | - const struct grf_reg *reg = &hw->grf_regs[index]; |
---|
236 | | - unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift); |
---|
| 239 | + const struct grf_reg *reg = NULL; |
---|
| 240 | + unsigned int val = 0; |
---|
237 | 241 | |
---|
| 242 | + if (index >= hw->drv_data->num_grf_regs) |
---|
| 243 | + return; |
---|
| 244 | + |
---|
| 245 | + reg = &hw->grf_regs[index]; |
---|
| 246 | + val = HIWORD_UPDATE(value, reg->mask, reg->shift); |
---|
238 | 247 | if (reg->mask) |
---|
239 | 248 | regmap_write(hw->regmap_sys_grf, reg->offset, val); |
---|
240 | 249 | } |
---|
.. | .. |
---|
242 | 251 | static inline void write_grf_reg(struct csi2_dphy_hw *hw, |
---|
243 | 252 | int index, u8 value) |
---|
244 | 253 | { |
---|
245 | | - const struct grf_reg *reg = &hw->grf_regs[index]; |
---|
246 | | - unsigned int val = HIWORD_UPDATE(value, reg->mask, reg->shift); |
---|
| 254 | + const struct grf_reg *reg = NULL; |
---|
| 255 | + unsigned int val = 0; |
---|
247 | 256 | |
---|
| 257 | + if (index >= hw->drv_data->num_grf_regs) |
---|
| 258 | + return; |
---|
| 259 | + |
---|
| 260 | + reg = &hw->grf_regs[index]; |
---|
| 261 | + val = HIWORD_UPDATE(value, reg->mask, reg->shift); |
---|
248 | 262 | if (reg->mask) |
---|
249 | 263 | regmap_write(hw->regmap_grf, reg->offset, val); |
---|
250 | 264 | } |
---|
251 | 265 | |
---|
252 | 266 | static inline u32 read_grf_reg(struct csi2_dphy_hw *hw, int index) |
---|
253 | 267 | { |
---|
254 | | - const struct grf_reg *reg = &hw->grf_regs[index]; |
---|
| 268 | + const struct grf_reg *reg = NULL; |
---|
255 | 269 | unsigned int val = 0; |
---|
256 | 270 | |
---|
| 271 | + if (index >= hw->drv_data->num_grf_regs) |
---|
| 272 | + return -EINVAL; |
---|
| 273 | + |
---|
| 274 | + reg = &hw->grf_regs[index]; |
---|
257 | 275 | if (reg->mask) { |
---|
258 | 276 | regmap_read(hw->regmap_grf, reg->offset, &val); |
---|
259 | 277 | val = (val >> reg->shift) & reg->mask; |
---|
.. | .. |
---|
265 | 283 | static inline void write_csi2_dphy_reg(struct csi2_dphy_hw *hw, |
---|
266 | 284 | int index, u32 value) |
---|
267 | 285 | { |
---|
268 | | - const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index]; |
---|
| 286 | + const struct csi2dphy_reg *reg = NULL; |
---|
269 | 287 | |
---|
| 288 | + if (index >= hw->drv_data->num_csi2dphy_regs) |
---|
| 289 | + return; |
---|
| 290 | + |
---|
| 291 | + reg = &hw->csi2dphy_regs[index]; |
---|
270 | 292 | if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) || |
---|
271 | 293 | (index == CSI2PHY_CLK_LANE_ENABLE) || |
---|
272 | 294 | (index != CSI2PHY_REG_CTRL_LANE_ENABLE && |
---|
.. | .. |
---|
277 | 299 | static inline void write_csi2_dphy_reg_mask(struct csi2_dphy_hw *hw, |
---|
278 | 300 | int index, u32 value, u32 mask) |
---|
279 | 301 | { |
---|
280 | | - const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index]; |
---|
| 302 | + const struct csi2dphy_reg *reg = NULL; |
---|
281 | 303 | u32 read_val = 0; |
---|
282 | 304 | |
---|
| 305 | + if (index >= hw->drv_data->num_csi2dphy_regs) |
---|
| 306 | + return; |
---|
| 307 | + |
---|
| 308 | + reg = &hw->csi2dphy_regs[index]; |
---|
283 | 309 | read_val = readl(hw->hw_base_addr + reg->offset); |
---|
284 | 310 | read_val &= ~mask; |
---|
285 | 311 | read_val |= value; |
---|
.. | .. |
---|
289 | 315 | static inline void read_csi2_dphy_reg(struct csi2_dphy_hw *hw, |
---|
290 | 316 | int index, u32 *value) |
---|
291 | 317 | { |
---|
292 | | - const struct csi2dphy_reg *reg = &hw->csi2dphy_regs[index]; |
---|
| 318 | + const struct csi2dphy_reg *reg = NULL; |
---|
293 | 319 | |
---|
| 320 | + if (index >= hw->drv_data->num_csi2dphy_regs) |
---|
| 321 | + return; |
---|
| 322 | + |
---|
| 323 | + reg = &hw->csi2dphy_regs[index]; |
---|
294 | 324 | if ((index == CSI2PHY_REG_CTRL_LANE_ENABLE) || |
---|
295 | 325 | (index == CSI2PHY_CLK_LANE_ENABLE) || |
---|
296 | 326 | (index != CSI2PHY_REG_CTRL_LANE_ENABLE && |
---|
.. | .. |
---|
397 | 427 | [CSI2PHY_CLK1_THS_SETTLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_WR_THS_SETTLE), |
---|
398 | 428 | [CSI2PHY_CLK1_CALIB_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CALIB_EN), |
---|
399 | 429 | [CSI2PHY_CLK1_LANE_ENABLE] = CSI2PHY_REG(CSI2_DPHY_CLK1_LANE_EN), |
---|
| 430 | + [CSI2PHY_CLK_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK_CONTINUE_MODE), |
---|
| 431 | + [CSI2PHY_CLK1_CONTINUE_MODE] = CSI2PHY_REG(CSI2_DPHY_CLK1_CONTINUE_MODE), |
---|
400 | 432 | }; |
---|
401 | 433 | |
---|
402 | 434 | static const struct grf_reg rv1106_grf_dphy_regs[] = { |
---|
.. | .. |
---|
709 | 741 | val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
710 | 742 | CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) | |
---|
711 | 743 | (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); |
---|
| 744 | + if (sensor->mbus.flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) |
---|
| 745 | + write_csi2_dphy_reg(hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30); |
---|
712 | 746 | } else { |
---|
713 | 747 | if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT))) |
---|
714 | 748 | val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); |
---|
715 | 749 | |
---|
716 | | - if (dphy->phy_index % 3 == DPHY1) |
---|
| 750 | + if (dphy->phy_index % 3 == DPHY1) { |
---|
717 | 751 | val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
718 | 752 | CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT); |
---|
| 753 | + if (sensor->mbus.flags & |
---|
| 754 | + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) |
---|
| 755 | + write_csi2_dphy_reg( |
---|
| 756 | + hw, CSI2PHY_CLK_CONTINUE_MODE, 0x30); |
---|
| 757 | + } |
---|
719 | 758 | |
---|
720 | 759 | if (dphy->phy_index % 3 == DPHY2) { |
---|
721 | 760 | val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
722 | 761 | CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT); |
---|
723 | 762 | if (hw->drv_data->chip_id >= CHIP_ID_RK3588) |
---|
724 | 763 | write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6)); |
---|
| 764 | + if (sensor->mbus.flags & |
---|
| 765 | + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) |
---|
| 766 | + write_csi2_dphy_reg( |
---|
| 767 | + hw, CSI2PHY_CLK1_CONTINUE_MODE, 0x30); |
---|
725 | 768 | } |
---|
726 | 769 | } |
---|
727 | 770 | val |= pre_val; |
---|
.. | .. |
---|
859 | 902 | |
---|
860 | 903 | write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, 0x01); |
---|
861 | 904 | csi2_dphy_hw_do_reset(hw); |
---|
862 | | - usleep_range(500, 1000); |
---|
863 | 905 | |
---|
864 | 906 | mutex_unlock(&hw->mutex); |
---|
865 | 907 | |
---|
| 908 | + return 0; |
---|
| 909 | +} |
---|
| 910 | + |
---|
| 911 | +static int csi2_dphy_hw_quick_stream_on(struct csi2_dphy *dphy, |
---|
| 912 | + struct v4l2_subdev *sd) |
---|
| 913 | +{ |
---|
| 914 | + struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); |
---|
| 915 | + struct csi2_sensor *sensor; |
---|
| 916 | + struct csi2_dphy_hw *hw = dphy->dphy_hw; |
---|
| 917 | + u32 val = 0, pre_val = 0; |
---|
| 918 | + |
---|
| 919 | + if (!sensor_sd) |
---|
| 920 | + return -ENODEV; |
---|
| 921 | + sensor = sd_to_sensor(dphy, sensor_sd); |
---|
| 922 | + if (!sensor) |
---|
| 923 | + return -ENODEV; |
---|
| 924 | + |
---|
| 925 | + read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val); |
---|
| 926 | + if (hw->lane_mode == LANE_MODE_FULL) { |
---|
| 927 | + val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
| 928 | + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) | |
---|
| 929 | + (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); |
---|
| 930 | + } else { |
---|
| 931 | + if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT))) |
---|
| 932 | + val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); |
---|
| 933 | + |
---|
| 934 | + if (dphy->phy_index % 3 == DPHY1) |
---|
| 935 | + val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
| 936 | + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT); |
---|
| 937 | + |
---|
| 938 | + if (dphy->phy_index % 3 == DPHY2) { |
---|
| 939 | + val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
| 940 | + CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT); |
---|
| 941 | + if (hw->drv_data->chip_id >= CHIP_ID_RK3588) |
---|
| 942 | + write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6)); |
---|
| 943 | + } |
---|
| 944 | + } |
---|
| 945 | + pre_val |= val; |
---|
| 946 | + write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val); |
---|
| 947 | + return 0; |
---|
| 948 | +} |
---|
| 949 | + |
---|
| 950 | +static int csi2_dphy_hw_quick_stream_off(struct csi2_dphy *dphy, |
---|
| 951 | + struct v4l2_subdev *sd) |
---|
| 952 | +{ |
---|
| 953 | + struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); |
---|
| 954 | + struct csi2_sensor *sensor; |
---|
| 955 | + struct csi2_dphy_hw *hw = dphy->dphy_hw; |
---|
| 956 | + u32 val = 0, pre_val = 0; |
---|
| 957 | + |
---|
| 958 | + if (!sensor_sd) |
---|
| 959 | + return -ENODEV; |
---|
| 960 | + sensor = sd_to_sensor(dphy, sensor_sd); |
---|
| 961 | + if (!sensor) |
---|
| 962 | + return -ENODEV; |
---|
| 963 | + |
---|
| 964 | + read_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, &pre_val); |
---|
| 965 | + if (hw->lane_mode == LANE_MODE_FULL) { |
---|
| 966 | + val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
| 967 | + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT) | |
---|
| 968 | + (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); |
---|
| 969 | + } else { |
---|
| 970 | + if (!(pre_val & (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT))) |
---|
| 971 | + val |= (0x1 << CSI2_DPHY_CTRL_CLKLANE_ENABLE_OFFSET_BIT); |
---|
| 972 | + |
---|
| 973 | + if (dphy->phy_index % 3 == DPHY1) |
---|
| 974 | + val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
| 975 | + CSI2_DPHY_CTRL_DATALANE_ENABLE_OFFSET_BIT); |
---|
| 976 | + |
---|
| 977 | + if (dphy->phy_index % 3 == DPHY2) { |
---|
| 978 | + val |= (GENMASK(sensor->lanes - 1, 0) << |
---|
| 979 | + CSI2_DPHY_CTRL_DATALANE_SPLIT_LANE2_3_OFFSET_BIT); |
---|
| 980 | + if (hw->drv_data->chip_id >= CHIP_ID_RK3588) |
---|
| 981 | + write_csi2_dphy_reg(hw, CSI2PHY_CLK1_LANE_ENABLE, BIT(6)); |
---|
| 982 | + } |
---|
| 983 | + } |
---|
| 984 | + pre_val &= ~val; |
---|
| 985 | + write_csi2_dphy_reg(hw, CSI2PHY_REG_CTRL_LANE_ENABLE, pre_val); |
---|
866 | 986 | return 0; |
---|
867 | 987 | } |
---|
868 | 988 | |
---|
.. | .. |
---|
913 | 1033 | .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, |
---|
914 | 1034 | .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), |
---|
915 | 1035 | .csi2dphy_regs = rk3568_csi2dphy_regs, |
---|
| 1036 | + .num_csi2dphy_regs = ARRAY_SIZE(rk3568_csi2dphy_regs), |
---|
916 | 1037 | .grf_regs = rk3568_grf_dphy_regs, |
---|
| 1038 | + .num_grf_regs = ARRAY_SIZE(rk3568_grf_dphy_regs), |
---|
917 | 1039 | .individual_init = rk3568_csi2_dphy_hw_individual_init, |
---|
918 | 1040 | .chip_id = CHIP_ID_RK3568, |
---|
919 | 1041 | .stream_on = csi2_dphy_hw_stream_on, |
---|
.. | .. |
---|
924 | 1046 | .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, |
---|
925 | 1047 | .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), |
---|
926 | 1048 | .csi2dphy_regs = rk3588_csi2dphy_regs, |
---|
| 1049 | + .num_csi2dphy_regs = ARRAY_SIZE(rk3588_csi2dphy_regs), |
---|
927 | 1050 | .grf_regs = rk3588_grf_dphy_regs, |
---|
| 1051 | + .num_grf_regs = ARRAY_SIZE(rk3588_grf_dphy_regs), |
---|
928 | 1052 | .individual_init = rk3588_csi2_dphy_hw_individual_init, |
---|
929 | 1053 | .chip_id = CHIP_ID_RK3588, |
---|
930 | 1054 | .stream_on = csi2_dphy_hw_stream_on, |
---|
.. | .. |
---|
935 | 1059 | .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, |
---|
936 | 1060 | .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), |
---|
937 | 1061 | .csi2dphy_regs = rv1106_csi2dphy_regs, |
---|
| 1062 | + .num_csi2dphy_regs = ARRAY_SIZE(rv1106_csi2dphy_regs), |
---|
938 | 1063 | .grf_regs = rv1106_grf_dphy_regs, |
---|
| 1064 | + .num_grf_regs = ARRAY_SIZE(rv1106_grf_dphy_regs), |
---|
939 | 1065 | .individual_init = rv1106_csi2_dphy_hw_individual_init, |
---|
940 | 1066 | .chip_id = CHIP_ID_RV1106, |
---|
941 | 1067 | .stream_on = csi2_dphy_hw_stream_on, |
---|
.. | .. |
---|
946 | 1072 | .hsfreq_ranges = rk3568_csi2_dphy_hw_hsfreq_ranges, |
---|
947 | 1073 | .num_hsfreq_ranges = ARRAY_SIZE(rk3568_csi2_dphy_hw_hsfreq_ranges), |
---|
948 | 1074 | .csi2dphy_regs = rk3562_csi2dphy_regs, |
---|
| 1075 | + .num_csi2dphy_regs = ARRAY_SIZE(rk3562_csi2dphy_regs), |
---|
949 | 1076 | .grf_regs = rk3562_grf_dphy_regs, |
---|
| 1077 | + .num_grf_regs = ARRAY_SIZE(rk3562_grf_dphy_regs), |
---|
950 | 1078 | .individual_init = rk3562_csi2_dphy_hw_individual_init, |
---|
951 | 1079 | .chip_id = CHIP_ID_RK3562, |
---|
952 | 1080 | .stream_on = csi2_dphy_hw_stream_on, |
---|
.. | .. |
---|
1024 | 1152 | dphy_hw->drv_data = drv_data; |
---|
1025 | 1153 | dphy_hw->lane_mode = LANE_MODE_UNDEF; |
---|
1026 | 1154 | dphy_hw->grf_regs = drv_data->grf_regs; |
---|
1027 | | - dphy_hw->txrx_regs = drv_data->txrx_regs; |
---|
1028 | 1155 | dphy_hw->csi2dphy_regs = drv_data->csi2dphy_regs; |
---|
1029 | 1156 | |
---|
1030 | 1157 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
.. | .. |
---|
1041 | 1168 | } |
---|
1042 | 1169 | dphy_hw->stream_on = drv_data->stream_on; |
---|
1043 | 1170 | dphy_hw->stream_off = drv_data->stream_off; |
---|
| 1171 | + dphy_hw->quick_stream_on = csi2_dphy_hw_quick_stream_on; |
---|
| 1172 | + dphy_hw->quick_stream_off = csi2_dphy_hw_quick_stream_off; |
---|
1044 | 1173 | |
---|
1045 | 1174 | if (drv_data->chip_id == CHIP_ID_RV1106) { |
---|
1046 | 1175 | dphy_hw->ttl_mode_enable = csi2_dphy_hw_ttl_mode_enable; |
---|