1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT) 2 /* 3 * Rockchip ISP1 Driver - V4l resizer device 4 * 5 * Copyright (C) 2019 Collabora, Ltd. 6 * 7 * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd. 8 * Copyright (C) 2017 Rockchip Electronics Co., Ltd. 9 */ 10 11 #include "rkisp1-common.h" 12 13 #define RKISP1_RSZ_SP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_selfpath" 14 #define RKISP1_RSZ_MP_DEV_NAME RKISP1_DRIVER_NAME "_resizer_mainpath" 15 16 #define RKISP1_DEF_FMT MEDIA_BUS_FMT_YUYV8_2X8 17 #define RKISP1_DEF_PIXEL_ENC V4L2_PIXEL_ENC_YUV 18 19 struct rkisp1_rsz_yuv_mbus_info { 20 u32 mbus_code; 21 u32 hdiv; 22 u32 vdiv; 23 }; 24 25 static const struct rkisp1_rsz_yuv_mbus_info rkisp1_rsz_yuv_src_formats[] = { 26 { 27 .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, /* YUV422 */ 28 .hdiv = 2, 29 .vdiv = 1, 30 }, 31 { 32 .mbus_code = MEDIA_BUS_FMT_YUYV8_1_5X8, /* YUV420 */ 33 .hdiv = 2, 34 .vdiv = 2, 35 }, 36 }; 37 38 static const struct rkisp1_rsz_yuv_mbus_info *rkisp1_rsz_get_yuv_mbus_info(u32 mbus_code) 39 { 40 unsigned int i; 41 42 for (i = 0; i < ARRAY_SIZE(rkisp1_rsz_yuv_src_formats); i++) { 43 if (rkisp1_rsz_yuv_src_formats[i].mbus_code == mbus_code) 44 return &rkisp1_rsz_yuv_src_formats[i]; 45 } 46 47 return NULL; 48 } 49 50 enum rkisp1_shadow_regs_when { 51 RKISP1_SHADOW_REGS_SYNC, 52 RKISP1_SHADOW_REGS_ASYNC, 53 }; 54 55 struct rkisp1_rsz_config { 56 /* constrains */ 57 const int max_rsz_width; 58 const int max_rsz_height; 59 const int min_rsz_width; 60 const int min_rsz_height; 61 /* registers */ 62 struct { 63 u32 ctrl; 64 u32 ctrl_shd; 65 u32 scale_hy; 66 u32 scale_hcr; 67 u32 scale_hcb; 68 u32 scale_vy; 69 u32 scale_vc; 70 u32 scale_lut; 71 u32 scale_lut_addr; 72 u32 scale_hy_shd; 73 u32 scale_hcr_shd; 74 u32 scale_hcb_shd; 75 u32 scale_vy_shd; 76 u32 scale_vc_shd; 77 u32 phase_hy; 78 u32 phase_hc; 79 u32 phase_vy; 80 u32 phase_vc; 81 u32 phase_hy_shd; 82 u32 phase_hc_shd; 83 u32 phase_vy_shd; 84 u32 phase_vc_shd; 85 } rsz; 86 struct { 87 u32 ctrl; 88 u32 yuvmode_mask; 89 u32 rawmode_mask; 90 u32 h_offset; 91 u32 v_offset; 92 u32 h_size; 93 u32 v_size; 94 } dual_crop; 95 }; 96 97 static const struct rkisp1_rsz_config rkisp1_rsz_config_mp = { 98 /* constraints */ 99 .max_rsz_width = RKISP1_RSZ_MP_SRC_MAX_WIDTH, 100 .max_rsz_height = RKISP1_RSZ_MP_SRC_MAX_HEIGHT, 101 .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH, 102 .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT, 103 /* registers */ 104 .rsz = { 105 .ctrl = RKISP1_CIF_MRSZ_CTRL, 106 .scale_hy = RKISP1_CIF_MRSZ_SCALE_HY, 107 .scale_hcr = RKISP1_CIF_MRSZ_SCALE_HCR, 108 .scale_hcb = RKISP1_CIF_MRSZ_SCALE_HCB, 109 .scale_vy = RKISP1_CIF_MRSZ_SCALE_VY, 110 .scale_vc = RKISP1_CIF_MRSZ_SCALE_VC, 111 .scale_lut = RKISP1_CIF_MRSZ_SCALE_LUT, 112 .scale_lut_addr = RKISP1_CIF_MRSZ_SCALE_LUT_ADDR, 113 .scale_hy_shd = RKISP1_CIF_MRSZ_SCALE_HY_SHD, 114 .scale_hcr_shd = RKISP1_CIF_MRSZ_SCALE_HCR_SHD, 115 .scale_hcb_shd = RKISP1_CIF_MRSZ_SCALE_HCB_SHD, 116 .scale_vy_shd = RKISP1_CIF_MRSZ_SCALE_VY_SHD, 117 .scale_vc_shd = RKISP1_CIF_MRSZ_SCALE_VC_SHD, 118 .phase_hy = RKISP1_CIF_MRSZ_PHASE_HY, 119 .phase_hc = RKISP1_CIF_MRSZ_PHASE_HC, 120 .phase_vy = RKISP1_CIF_MRSZ_PHASE_VY, 121 .phase_vc = RKISP1_CIF_MRSZ_PHASE_VC, 122 .ctrl_shd = RKISP1_CIF_MRSZ_CTRL_SHD, 123 .phase_hy_shd = RKISP1_CIF_MRSZ_PHASE_HY_SHD, 124 .phase_hc_shd = RKISP1_CIF_MRSZ_PHASE_HC_SHD, 125 .phase_vy_shd = RKISP1_CIF_MRSZ_PHASE_VY_SHD, 126 .phase_vc_shd = RKISP1_CIF_MRSZ_PHASE_VC_SHD, 127 }, 128 .dual_crop = { 129 .ctrl = RKISP1_CIF_DUAL_CROP_CTRL, 130 .yuvmode_mask = RKISP1_CIF_DUAL_CROP_MP_MODE_YUV, 131 .rawmode_mask = RKISP1_CIF_DUAL_CROP_MP_MODE_RAW, 132 .h_offset = RKISP1_CIF_DUAL_CROP_M_H_OFFS, 133 .v_offset = RKISP1_CIF_DUAL_CROP_M_V_OFFS, 134 .h_size = RKISP1_CIF_DUAL_CROP_M_H_SIZE, 135 .v_size = RKISP1_CIF_DUAL_CROP_M_V_SIZE, 136 }, 137 }; 138 139 static const struct rkisp1_rsz_config rkisp1_rsz_config_sp = { 140 /* constraints */ 141 .max_rsz_width = RKISP1_RSZ_SP_SRC_MAX_WIDTH, 142 .max_rsz_height = RKISP1_RSZ_SP_SRC_MAX_HEIGHT, 143 .min_rsz_width = RKISP1_RSZ_SRC_MIN_WIDTH, 144 .min_rsz_height = RKISP1_RSZ_SRC_MIN_HEIGHT, 145 /* registers */ 146 .rsz = { 147 .ctrl = RKISP1_CIF_SRSZ_CTRL, 148 .scale_hy = RKISP1_CIF_SRSZ_SCALE_HY, 149 .scale_hcr = RKISP1_CIF_SRSZ_SCALE_HCR, 150 .scale_hcb = RKISP1_CIF_SRSZ_SCALE_HCB, 151 .scale_vy = RKISP1_CIF_SRSZ_SCALE_VY, 152 .scale_vc = RKISP1_CIF_SRSZ_SCALE_VC, 153 .scale_lut = RKISP1_CIF_SRSZ_SCALE_LUT, 154 .scale_lut_addr = RKISP1_CIF_SRSZ_SCALE_LUT_ADDR, 155 .scale_hy_shd = RKISP1_CIF_SRSZ_SCALE_HY_SHD, 156 .scale_hcr_shd = RKISP1_CIF_SRSZ_SCALE_HCR_SHD, 157 .scale_hcb_shd = RKISP1_CIF_SRSZ_SCALE_HCB_SHD, 158 .scale_vy_shd = RKISP1_CIF_SRSZ_SCALE_VY_SHD, 159 .scale_vc_shd = RKISP1_CIF_SRSZ_SCALE_VC_SHD, 160 .phase_hy = RKISP1_CIF_SRSZ_PHASE_HY, 161 .phase_hc = RKISP1_CIF_SRSZ_PHASE_HC, 162 .phase_vy = RKISP1_CIF_SRSZ_PHASE_VY, 163 .phase_vc = RKISP1_CIF_SRSZ_PHASE_VC, 164 .ctrl_shd = RKISP1_CIF_SRSZ_CTRL_SHD, 165 .phase_hy_shd = RKISP1_CIF_SRSZ_PHASE_HY_SHD, 166 .phase_hc_shd = RKISP1_CIF_SRSZ_PHASE_HC_SHD, 167 .phase_vy_shd = RKISP1_CIF_SRSZ_PHASE_VY_SHD, 168 .phase_vc_shd = RKISP1_CIF_SRSZ_PHASE_VC_SHD, 169 }, 170 .dual_crop = { 171 .ctrl = RKISP1_CIF_DUAL_CROP_CTRL, 172 .yuvmode_mask = RKISP1_CIF_DUAL_CROP_SP_MODE_YUV, 173 .rawmode_mask = RKISP1_CIF_DUAL_CROP_SP_MODE_RAW, 174 .h_offset = RKISP1_CIF_DUAL_CROP_S_H_OFFS, 175 .v_offset = RKISP1_CIF_DUAL_CROP_S_V_OFFS, 176 .h_size = RKISP1_CIF_DUAL_CROP_S_H_SIZE, 177 .v_size = RKISP1_CIF_DUAL_CROP_S_V_SIZE, 178 }, 179 }; 180 181 static struct v4l2_mbus_framefmt * 182 rkisp1_rsz_get_pad_fmt(struct rkisp1_resizer *rsz, 183 struct v4l2_subdev_pad_config *cfg, 184 unsigned int pad, u32 which) 185 { 186 if (which == V4L2_SUBDEV_FORMAT_TRY) 187 return v4l2_subdev_get_try_format(&rsz->sd, cfg, pad); 188 else 189 return v4l2_subdev_get_try_format(&rsz->sd, rsz->pad_cfg, pad); 190 } 191 192 static struct v4l2_rect * 193 rkisp1_rsz_get_pad_crop(struct rkisp1_resizer *rsz, 194 struct v4l2_subdev_pad_config *cfg, 195 unsigned int pad, u32 which) 196 { 197 if (which == V4L2_SUBDEV_FORMAT_TRY) 198 return v4l2_subdev_get_try_crop(&rsz->sd, cfg, pad); 199 else 200 return v4l2_subdev_get_try_crop(&rsz->sd, rsz->pad_cfg, pad); 201 } 202 203 /* ---------------------------------------------------------------------------- 204 * Dual crop hw configs 205 */ 206 207 static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz, 208 enum rkisp1_shadow_regs_when when) 209 { 210 u32 dc_ctrl = rkisp1_read(rsz->rkisp1, rsz->config->dual_crop.ctrl); 211 u32 mask = ~(rsz->config->dual_crop.yuvmode_mask | 212 rsz->config->dual_crop.rawmode_mask); 213 214 dc_ctrl &= mask; 215 if (when == RKISP1_SHADOW_REGS_ASYNC) 216 dc_ctrl |= RKISP1_CIF_DUAL_CROP_GEN_CFG_UPD; 217 else 218 dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD; 219 rkisp1_write(rsz->rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl); 220 } 221 222 /* configure dual-crop unit */ 223 static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz) 224 { 225 struct rkisp1_device *rkisp1 = rsz->rkisp1; 226 struct v4l2_mbus_framefmt *sink_fmt; 227 struct v4l2_rect *sink_crop; 228 u32 dc_ctrl; 229 230 sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK, 231 V4L2_SUBDEV_FORMAT_ACTIVE); 232 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK, 233 V4L2_SUBDEV_FORMAT_ACTIVE); 234 235 if (sink_crop->width == sink_fmt->width && 236 sink_crop->height == sink_fmt->height && 237 sink_crop->left == 0 && sink_crop->top == 0) { 238 rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_SYNC); 239 dev_dbg(rkisp1->dev, "capture %d crop disabled\n", rsz->id); 240 return; 241 } 242 243 dc_ctrl = rkisp1_read(rkisp1, rsz->config->dual_crop.ctrl); 244 rkisp1_write(rkisp1, sink_crop->left, rsz->config->dual_crop.h_offset); 245 rkisp1_write(rkisp1, sink_crop->top, rsz->config->dual_crop.v_offset); 246 rkisp1_write(rkisp1, sink_crop->width, rsz->config->dual_crop.h_size); 247 rkisp1_write(rkisp1, sink_crop->height, rsz->config->dual_crop.v_size); 248 dc_ctrl |= rsz->config->dual_crop.yuvmode_mask; 249 dc_ctrl |= RKISP1_CIF_DUAL_CROP_CFG_UPD; 250 rkisp1_write(rkisp1, dc_ctrl, rsz->config->dual_crop.ctrl); 251 252 dev_dbg(rkisp1->dev, "stream %d crop: %dx%d -> %dx%d\n", rsz->id, 253 sink_fmt->width, sink_fmt->height, 254 sink_crop->width, sink_crop->height); 255 } 256 257 /* ---------------------------------------------------------------------------- 258 * Resizer hw configs 259 */ 260 261 static void rkisp1_rsz_dump_regs(struct rkisp1_resizer *rsz) 262 { 263 dev_dbg(rsz->rkisp1->dev, 264 "RSZ_CTRL 0x%08x/0x%08x\n" 265 "RSZ_SCALE_HY %d/%d\n" 266 "RSZ_SCALE_HCB %d/%d\n" 267 "RSZ_SCALE_HCR %d/%d\n" 268 "RSZ_SCALE_VY %d/%d\n" 269 "RSZ_SCALE_VC %d/%d\n" 270 "RSZ_PHASE_HY %d/%d\n" 271 "RSZ_PHASE_HC %d/%d\n" 272 "RSZ_PHASE_VY %d/%d\n" 273 "RSZ_PHASE_VC %d/%d\n", 274 rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl), 275 rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl_shd), 276 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy), 277 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hy_shd), 278 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb), 279 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcb_shd), 280 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr), 281 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_hcr_shd), 282 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy), 283 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vy_shd), 284 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc), 285 rkisp1_read(rsz->rkisp1, rsz->config->rsz.scale_vc_shd), 286 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy), 287 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hy_shd), 288 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc), 289 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_hc_shd), 290 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy), 291 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vy_shd), 292 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc), 293 rkisp1_read(rsz->rkisp1, rsz->config->rsz.phase_vc_shd)); 294 } 295 296 static void rkisp1_rsz_update_shadow(struct rkisp1_resizer *rsz, 297 enum rkisp1_shadow_regs_when when) 298 { 299 u32 ctrl_cfg = rkisp1_read(rsz->rkisp1, rsz->config->rsz.ctrl); 300 301 if (when == RKISP1_SHADOW_REGS_ASYNC) 302 ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD_AUTO; 303 else 304 ctrl_cfg |= RKISP1_CIF_RSZ_CTRL_CFG_UPD; 305 306 rkisp1_write(rsz->rkisp1, ctrl_cfg, rsz->config->rsz.ctrl); 307 } 308 309 static u32 rkisp1_rsz_calc_ratio(u32 len_sink, u32 len_src) 310 { 311 if (len_sink < len_src) 312 return ((len_sink - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) / 313 (len_src - 1); 314 315 return ((len_src - 1) * RKISP1_CIF_RSZ_SCALER_FACTOR) / 316 (len_sink - 1) + 1; 317 } 318 319 static void rkisp1_rsz_disable(struct rkisp1_resizer *rsz, 320 enum rkisp1_shadow_regs_when when) 321 { 322 rkisp1_write(rsz->rkisp1, 0, rsz->config->rsz.ctrl); 323 324 if (when == RKISP1_SHADOW_REGS_SYNC) 325 rkisp1_rsz_update_shadow(rsz, when); 326 } 327 328 static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz, 329 struct v4l2_rect *sink_y, 330 struct v4l2_rect *sink_c, 331 struct v4l2_rect *src_y, 332 struct v4l2_rect *src_c, 333 enum rkisp1_shadow_regs_when when) 334 { 335 struct rkisp1_device *rkisp1 = rsz->rkisp1; 336 u32 ratio, rsz_ctrl = 0; 337 unsigned int i; 338 339 /* No phase offset */ 340 rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hy); 341 rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_hc); 342 rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vy); 343 rkisp1_write(rkisp1, 0, rsz->config->rsz.phase_vc); 344 345 /* Linear interpolation */ 346 for (i = 0; i < 64; i++) { 347 rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut_addr); 348 rkisp1_write(rkisp1, i, rsz->config->rsz.scale_lut); 349 } 350 351 if (sink_y->width != src_y->width) { 352 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_ENABLE; 353 if (sink_y->width < src_y->width) 354 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HY_UP; 355 ratio = rkisp1_rsz_calc_ratio(sink_y->width, src_y->width); 356 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hy); 357 } 358 359 if (sink_c->width != src_c->width) { 360 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_ENABLE; 361 if (sink_c->width < src_c->width) 362 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_HC_UP; 363 ratio = rkisp1_rsz_calc_ratio(sink_c->width, src_c->width); 364 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcb); 365 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_hcr); 366 } 367 368 if (sink_y->height != src_y->height) { 369 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_ENABLE; 370 if (sink_y->height < src_y->height) 371 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VY_UP; 372 ratio = rkisp1_rsz_calc_ratio(sink_y->height, src_y->height); 373 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vy); 374 } 375 376 if (sink_c->height != src_c->height) { 377 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_ENABLE; 378 if (sink_c->height < src_c->height) 379 rsz_ctrl |= RKISP1_CIF_RSZ_CTRL_SCALE_VC_UP; 380 ratio = rkisp1_rsz_calc_ratio(sink_c->height, src_c->height); 381 rkisp1_write(rkisp1, ratio, rsz->config->rsz.scale_vc); 382 } 383 384 rkisp1_write(rkisp1, rsz_ctrl, rsz->config->rsz.ctrl); 385 386 rkisp1_rsz_update_shadow(rsz, when); 387 } 388 389 static void rkisp1_rsz_config(struct rkisp1_resizer *rsz, 390 enum rkisp1_shadow_regs_when when) 391 { 392 const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info; 393 struct v4l2_rect sink_y, sink_c, src_y, src_c; 394 struct v4l2_mbus_framefmt *src_fmt, *sink_fmt; 395 struct v4l2_rect *sink_crop; 396 397 sink_crop = rkisp1_rsz_get_pad_crop(rsz, NULL, RKISP1_RSZ_PAD_SINK, 398 V4L2_SUBDEV_FORMAT_ACTIVE); 399 src_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SRC, 400 V4L2_SUBDEV_FORMAT_ACTIVE); 401 src_yuv_info = rkisp1_rsz_get_yuv_mbus_info(src_fmt->code); 402 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, NULL, RKISP1_RSZ_PAD_SINK, 403 V4L2_SUBDEV_FORMAT_ACTIVE); 404 sink_yuv_info = rkisp1_rsz_get_yuv_mbus_info(sink_fmt->code); 405 406 /* 407 * The resizer only works on yuv formats, 408 * so return if it is bayer format. 409 */ 410 if (rsz->pixel_enc == V4L2_PIXEL_ENC_BAYER) { 411 rkisp1_rsz_disable(rsz, when); 412 return; 413 } 414 415 sink_y.width = sink_crop->width; 416 sink_y.height = sink_crop->height; 417 src_y.width = src_fmt->width; 418 src_y.height = src_fmt->height; 419 420 sink_c.width = sink_y.width / sink_yuv_info->hdiv; 421 sink_c.height = sink_y.height / sink_yuv_info->vdiv; 422 423 /* 424 * The resizer is used not only to change the dimensions of the frame 425 * but also to change the scale for YUV formats, 426 * (4:2:2 -> 4:2:0 for example). So the width/height of the CbCr 427 * streams should be set according to the media bus format in the src pad. 428 */ 429 src_c.width = src_y.width / src_yuv_info->hdiv; 430 src_c.height = src_y.height / src_yuv_info->vdiv; 431 432 if (sink_c.width == src_c.width && sink_c.height == src_c.height) { 433 rkisp1_rsz_disable(rsz, when); 434 return; 435 } 436 437 dev_dbg(rsz->rkisp1->dev, "stream %d rsz/scale: %dx%d -> %dx%d\n", 438 rsz->id, sink_crop->width, sink_crop->height, 439 src_fmt->width, src_fmt->height); 440 dev_dbg(rsz->rkisp1->dev, "chroma scaling %dx%d -> %dx%d\n", 441 sink_c.width, sink_c.height, src_c.width, src_c.height); 442 443 /* set values in the hw */ 444 rkisp1_rsz_config_regs(rsz, &sink_y, &sink_c, &src_y, &src_c, when); 445 446 rkisp1_rsz_dump_regs(rsz); 447 } 448 449 /* ---------------------------------------------------------------------------- 450 * Subdev pad operations 451 */ 452 453 static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd, 454 struct v4l2_subdev_pad_config *cfg, 455 struct v4l2_subdev_mbus_code_enum *code) 456 { 457 struct rkisp1_resizer *rsz = 458 container_of(sd, struct rkisp1_resizer, sd); 459 struct v4l2_subdev_pad_config dummy_cfg; 460 u32 pad = code->pad; 461 int ret; 462 463 if (code->pad == RKISP1_RSZ_PAD_SRC) { 464 /* supported mbus codes on the src are the same as in the capture */ 465 struct rkisp1_capture *cap = &rsz->rkisp1->capture_devs[rsz->id]; 466 467 return rkisp1_cap_enum_mbus_codes(cap, code); 468 } 469 470 /* 471 * The selfpath capture doesn't support bayer formats. Therefore the selfpath resizer 472 * should support only YUV422 on the sink pad 473 */ 474 if (rsz->id == RKISP1_SELFPATH) { 475 if (code->index > 0) 476 return -EINVAL; 477 code->code = MEDIA_BUS_FMT_YUYV8_2X8; 478 return 0; 479 } 480 481 /* supported mbus codes on the sink pad are the same as isp src pad */ 482 code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO; 483 ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code, 484 &dummy_cfg, code); 485 486 /* restore pad */ 487 code->pad = pad; 488 code->flags = 0; 489 return ret; 490 } 491 492 static int rkisp1_rsz_init_config(struct v4l2_subdev *sd, 493 struct v4l2_subdev_pad_config *cfg) 494 { 495 struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; 496 struct v4l2_rect *sink_crop; 497 498 sink_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SRC); 499 sink_fmt->width = RKISP1_DEFAULT_WIDTH; 500 sink_fmt->height = RKISP1_DEFAULT_HEIGHT; 501 sink_fmt->field = V4L2_FIELD_NONE; 502 sink_fmt->code = RKISP1_DEF_FMT; 503 504 sink_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_RSZ_PAD_SINK); 505 sink_crop->width = RKISP1_DEFAULT_WIDTH; 506 sink_crop->height = RKISP1_DEFAULT_HEIGHT; 507 sink_crop->left = 0; 508 sink_crop->top = 0; 509 510 src_fmt = v4l2_subdev_get_try_format(sd, cfg, RKISP1_RSZ_PAD_SINK); 511 *src_fmt = *sink_fmt; 512 513 /* NOTE: there is no crop in the source pad, only in the sink */ 514 515 return 0; 516 } 517 518 static void rkisp1_rsz_set_src_fmt(struct rkisp1_resizer *rsz, 519 struct v4l2_subdev_pad_config *cfg, 520 struct v4l2_mbus_framefmt *format, 521 unsigned int which) 522 { 523 const struct rkisp1_isp_mbus_info *sink_mbus_info; 524 struct v4l2_mbus_framefmt *src_fmt, *sink_fmt; 525 526 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); 527 src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which); 528 sink_mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); 529 530 /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */ 531 if (sink_mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV && 532 rkisp1_rsz_get_yuv_mbus_info(format->code)) 533 src_fmt->code = format->code; 534 535 src_fmt->width = clamp_t(u32, format->width, 536 rsz->config->min_rsz_width, 537 rsz->config->max_rsz_width); 538 src_fmt->height = clamp_t(u32, format->height, 539 rsz->config->min_rsz_height, 540 rsz->config->max_rsz_height); 541 542 *format = *src_fmt; 543 } 544 545 static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz, 546 struct v4l2_subdev_pad_config *cfg, 547 struct v4l2_rect *r, 548 unsigned int which) 549 { 550 const struct rkisp1_isp_mbus_info *mbus_info; 551 struct v4l2_mbus_framefmt *sink_fmt; 552 struct v4l2_rect *sink_crop; 553 554 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); 555 sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, 556 which); 557 558 /* Not crop for MP bayer raw data */ 559 mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); 560 561 if (rsz->id == RKISP1_MAINPATH && 562 mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) { 563 sink_crop->left = 0; 564 sink_crop->top = 0; 565 sink_crop->width = sink_fmt->width; 566 sink_crop->height = sink_fmt->height; 567 568 *r = *sink_crop; 569 return; 570 } 571 572 sink_crop->left = ALIGN(r->left, 2); 573 sink_crop->width = ALIGN(r->width, 2); 574 sink_crop->top = r->top; 575 sink_crop->height = r->height; 576 rkisp1_sd_adjust_crop(sink_crop, sink_fmt); 577 578 *r = *sink_crop; 579 } 580 581 static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz, 582 struct v4l2_subdev_pad_config *cfg, 583 struct v4l2_mbus_framefmt *format, 584 unsigned int which) 585 { 586 const struct rkisp1_isp_mbus_info *mbus_info; 587 struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; 588 struct v4l2_rect *sink_crop; 589 590 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); 591 src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which); 592 sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, 593 which); 594 if (rsz->id == RKISP1_SELFPATH) 595 sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; 596 else 597 sink_fmt->code = format->code; 598 599 mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); 600 if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) { 601 sink_fmt->code = RKISP1_DEF_FMT; 602 mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); 603 } 604 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) 605 rsz->pixel_enc = mbus_info->pixel_enc; 606 607 /* Propagete to source pad */ 608 src_fmt->code = sink_fmt->code; 609 610 sink_fmt->width = clamp_t(u32, format->width, 611 RKISP1_ISP_MIN_WIDTH, 612 RKISP1_ISP_MAX_WIDTH); 613 sink_fmt->height = clamp_t(u32, format->height, 614 RKISP1_ISP_MIN_HEIGHT, 615 RKISP1_ISP_MAX_HEIGHT); 616 617 *format = *sink_fmt; 618 619 /* Update sink crop */ 620 rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which); 621 } 622 623 static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd, 624 struct v4l2_subdev_pad_config *cfg, 625 struct v4l2_subdev_format *fmt) 626 { 627 struct rkisp1_resizer *rsz = 628 container_of(sd, struct rkisp1_resizer, sd); 629 630 mutex_lock(&rsz->ops_lock); 631 fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which); 632 mutex_unlock(&rsz->ops_lock); 633 return 0; 634 } 635 636 static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd, 637 struct v4l2_subdev_pad_config *cfg, 638 struct v4l2_subdev_format *fmt) 639 { 640 struct rkisp1_resizer *rsz = 641 container_of(sd, struct rkisp1_resizer, sd); 642 643 mutex_lock(&rsz->ops_lock); 644 if (fmt->pad == RKISP1_RSZ_PAD_SINK) 645 rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which); 646 else 647 rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which); 648 649 mutex_unlock(&rsz->ops_lock); 650 return 0; 651 } 652 653 static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd, 654 struct v4l2_subdev_pad_config *cfg, 655 struct v4l2_subdev_selection *sel) 656 { 657 struct rkisp1_resizer *rsz = 658 container_of(sd, struct rkisp1_resizer, sd); 659 struct v4l2_mbus_framefmt *mf_sink; 660 int ret = 0; 661 662 if (sel->pad == RKISP1_RSZ_PAD_SRC) 663 return -EINVAL; 664 665 mutex_lock(&rsz->ops_lock); 666 switch (sel->target) { 667 case V4L2_SEL_TGT_CROP_BOUNDS: 668 mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, 669 sel->which); 670 sel->r.height = mf_sink->height; 671 sel->r.width = mf_sink->width; 672 sel->r.left = 0; 673 sel->r.top = 0; 674 break; 675 case V4L2_SEL_TGT_CROP: 676 sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, 677 sel->which); 678 break; 679 default: 680 ret = -EINVAL; 681 } 682 683 mutex_unlock(&rsz->ops_lock); 684 return ret; 685 } 686 687 static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd, 688 struct v4l2_subdev_pad_config *cfg, 689 struct v4l2_subdev_selection *sel) 690 { 691 struct rkisp1_resizer *rsz = 692 container_of(sd, struct rkisp1_resizer, sd); 693 694 if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC) 695 return -EINVAL; 696 697 dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__, 698 sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height); 699 700 mutex_lock(&rsz->ops_lock); 701 rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which); 702 mutex_unlock(&rsz->ops_lock); 703 704 return 0; 705 } 706 707 static const struct media_entity_operations rkisp1_rsz_media_ops = { 708 .link_validate = v4l2_subdev_link_validate, 709 }; 710 711 static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = { 712 .enum_mbus_code = rkisp1_rsz_enum_mbus_code, 713 .get_selection = rkisp1_rsz_get_selection, 714 .set_selection = rkisp1_rsz_set_selection, 715 .init_cfg = rkisp1_rsz_init_config, 716 .get_fmt = rkisp1_rsz_get_fmt, 717 .set_fmt = rkisp1_rsz_set_fmt, 718 .link_validate = v4l2_subdev_link_validate_default, 719 }; 720 721 /* ---------------------------------------------------------------------------- 722 * Stream operations 723 */ 724 725 static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable) 726 { 727 struct rkisp1_resizer *rsz = 728 container_of(sd, struct rkisp1_resizer, sd); 729 struct rkisp1_device *rkisp1 = rsz->rkisp1; 730 struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1]; 731 enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC; 732 733 if (!enable) { 734 rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC); 735 rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC); 736 return 0; 737 } 738 739 if (other->is_streaming) 740 when = RKISP1_SHADOW_REGS_ASYNC; 741 742 mutex_lock(&rsz->ops_lock); 743 rkisp1_rsz_config(rsz, when); 744 rkisp1_dcrop_config(rsz); 745 746 mutex_unlock(&rsz->ops_lock); 747 return 0; 748 } 749 750 static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = { 751 .s_stream = rkisp1_rsz_s_stream, 752 }; 753 754 static const struct v4l2_subdev_ops rkisp1_rsz_ops = { 755 .video = &rkisp1_rsz_video_ops, 756 .pad = &rkisp1_rsz_pad_ops, 757 }; 758 759 static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz) 760 { 761 v4l2_device_unregister_subdev(&rsz->sd); 762 media_entity_cleanup(&rsz->sd.entity); 763 } 764 765 static int rkisp1_rsz_register(struct rkisp1_resizer *rsz) 766 { 767 static const char * const dev_names[] = { 768 RKISP1_RSZ_MP_DEV_NAME, 769 RKISP1_RSZ_SP_DEV_NAME 770 }; 771 struct media_pad *pads = rsz->pads; 772 struct v4l2_subdev *sd = &rsz->sd; 773 int ret; 774 775 if (rsz->id == RKISP1_SELFPATH) 776 rsz->config = &rkisp1_rsz_config_sp; 777 else 778 rsz->config = &rkisp1_rsz_config_mp; 779 780 v4l2_subdev_init(sd, &rkisp1_rsz_ops); 781 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 782 sd->entity.ops = &rkisp1_rsz_media_ops; 783 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER; 784 sd->owner = THIS_MODULE; 785 strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name)); 786 787 pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK | 788 MEDIA_PAD_FL_MUST_CONNECT; 789 pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE | 790 MEDIA_PAD_FL_MUST_CONNECT; 791 792 rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC; 793 794 mutex_init(&rsz->ops_lock); 795 ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads); 796 if (ret) 797 return ret; 798 799 ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd); 800 if (ret) { 801 dev_err(sd->dev, "Failed to register resizer subdev\n"); 802 goto err_cleanup_media_entity; 803 } 804 805 rkisp1_rsz_init_config(sd, rsz->pad_cfg); 806 return 0; 807 808 err_cleanup_media_entity: 809 media_entity_cleanup(&sd->entity); 810 811 return ret; 812 } 813 814 int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1) 815 { 816 struct rkisp1_resizer *rsz; 817 unsigned int i, j; 818 int ret; 819 820 for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) { 821 rsz = &rkisp1->resizer_devs[i]; 822 rsz->rkisp1 = rkisp1; 823 rsz->id = i; 824 ret = rkisp1_rsz_register(rsz); 825 if (ret) 826 goto err_unreg_resizer_devs; 827 } 828 829 return 0; 830 831 err_unreg_resizer_devs: 832 for (j = 0; j < i; j++) { 833 rsz = &rkisp1->resizer_devs[j]; 834 rkisp1_rsz_unregister(rsz); 835 } 836 837 return ret; 838 } 839 840 void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1) 841 { 842 struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH]; 843 struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH]; 844 845 rkisp1_rsz_unregister(mp); 846 rkisp1_rsz_unregister(sp); 847 } 848