| .. | .. |
|---|
| 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; |
|---|