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 *mbus_info; 524 struct v4l2_mbus_framefmt *src_fmt; 525 526 src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which); 527 mbus_info = rkisp1_isp_mbus_info_get(src_fmt->code); 528 529 /* for YUV formats, userspace can change the mbus code on the src pad if it is supported */ 530 if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV && 531 rkisp1_rsz_get_yuv_mbus_info(format->code)) 532 src_fmt->code = format->code; 533 534 src_fmt->width = clamp_t(u32, format->width, 535 rsz->config->min_rsz_width, 536 rsz->config->max_rsz_width); 537 src_fmt->height = clamp_t(u32, format->height, 538 rsz->config->min_rsz_height, 539 rsz->config->max_rsz_height); 540 541 *format = *src_fmt; 542 } 543 544 static void rkisp1_rsz_set_sink_crop(struct rkisp1_resizer *rsz, 545 struct v4l2_subdev_pad_config *cfg, 546 struct v4l2_rect *r, 547 unsigned int which) 548 { 549 const struct rkisp1_isp_mbus_info *mbus_info; 550 struct v4l2_mbus_framefmt *sink_fmt; 551 struct v4l2_rect *sink_crop; 552 553 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); 554 sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, 555 which); 556 557 /* Not crop for MP bayer raw data */ 558 mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); 559 560 if (rsz->id == RKISP1_MAINPATH && 561 mbus_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) { 562 sink_crop->left = 0; 563 sink_crop->top = 0; 564 sink_crop->width = sink_fmt->width; 565 sink_crop->height = sink_fmt->height; 566 567 *r = *sink_crop; 568 return; 569 } 570 571 sink_crop->left = ALIGN(r->left, 2); 572 sink_crop->width = ALIGN(r->width, 2); 573 sink_crop->top = r->top; 574 sink_crop->height = r->height; 575 rkisp1_sd_adjust_crop(sink_crop, sink_fmt); 576 577 *r = *sink_crop; 578 } 579 580 static void rkisp1_rsz_set_sink_fmt(struct rkisp1_resizer *rsz, 581 struct v4l2_subdev_pad_config *cfg, 582 struct v4l2_mbus_framefmt *format, 583 unsigned int which) 584 { 585 const struct rkisp1_isp_mbus_info *mbus_info; 586 struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; 587 struct v4l2_rect *sink_crop; 588 589 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, which); 590 src_fmt = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SRC, which); 591 sink_crop = rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, 592 which); 593 if (rsz->id == RKISP1_SELFPATH) 594 sink_fmt->code = MEDIA_BUS_FMT_YUYV8_2X8; 595 else 596 sink_fmt->code = format->code; 597 598 mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); 599 if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) { 600 sink_fmt->code = RKISP1_DEF_FMT; 601 mbus_info = rkisp1_isp_mbus_info_get(sink_fmt->code); 602 } 603 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) 604 rsz->pixel_enc = mbus_info->pixel_enc; 605 606 /* Propagete to source pad */ 607 src_fmt->code = sink_fmt->code; 608 609 sink_fmt->width = clamp_t(u32, format->width, 610 RKISP1_ISP_MIN_WIDTH, 611 RKISP1_ISP_MAX_WIDTH); 612 sink_fmt->height = clamp_t(u32, format->height, 613 RKISP1_ISP_MIN_HEIGHT, 614 RKISP1_ISP_MAX_HEIGHT); 615 616 *format = *sink_fmt; 617 618 /* Update sink crop */ 619 rkisp1_rsz_set_sink_crop(rsz, cfg, sink_crop, which); 620 } 621 622 static int rkisp1_rsz_get_fmt(struct v4l2_subdev *sd, 623 struct v4l2_subdev_pad_config *cfg, 624 struct v4l2_subdev_format *fmt) 625 { 626 struct rkisp1_resizer *rsz = 627 container_of(sd, struct rkisp1_resizer, sd); 628 629 mutex_lock(&rsz->ops_lock); 630 fmt->format = *rkisp1_rsz_get_pad_fmt(rsz, cfg, fmt->pad, fmt->which); 631 mutex_unlock(&rsz->ops_lock); 632 return 0; 633 } 634 635 static int rkisp1_rsz_set_fmt(struct v4l2_subdev *sd, 636 struct v4l2_subdev_pad_config *cfg, 637 struct v4l2_subdev_format *fmt) 638 { 639 struct rkisp1_resizer *rsz = 640 container_of(sd, struct rkisp1_resizer, sd); 641 642 mutex_lock(&rsz->ops_lock); 643 if (fmt->pad == RKISP1_RSZ_PAD_SINK) 644 rkisp1_rsz_set_sink_fmt(rsz, cfg, &fmt->format, fmt->which); 645 else 646 rkisp1_rsz_set_src_fmt(rsz, cfg, &fmt->format, fmt->which); 647 648 mutex_unlock(&rsz->ops_lock); 649 return 0; 650 } 651 652 static int rkisp1_rsz_get_selection(struct v4l2_subdev *sd, 653 struct v4l2_subdev_pad_config *cfg, 654 struct v4l2_subdev_selection *sel) 655 { 656 struct rkisp1_resizer *rsz = 657 container_of(sd, struct rkisp1_resizer, sd); 658 struct v4l2_mbus_framefmt *mf_sink; 659 int ret = 0; 660 661 if (sel->pad == RKISP1_RSZ_PAD_SRC) 662 return -EINVAL; 663 664 mutex_lock(&rsz->ops_lock); 665 switch (sel->target) { 666 case V4L2_SEL_TGT_CROP_BOUNDS: 667 mf_sink = rkisp1_rsz_get_pad_fmt(rsz, cfg, RKISP1_RSZ_PAD_SINK, 668 sel->which); 669 sel->r.height = mf_sink->height; 670 sel->r.width = mf_sink->width; 671 sel->r.left = 0; 672 sel->r.top = 0; 673 break; 674 case V4L2_SEL_TGT_CROP: 675 sel->r = *rkisp1_rsz_get_pad_crop(rsz, cfg, RKISP1_RSZ_PAD_SINK, 676 sel->which); 677 break; 678 default: 679 ret = -EINVAL; 680 } 681 682 mutex_unlock(&rsz->ops_lock); 683 return ret; 684 } 685 686 static int rkisp1_rsz_set_selection(struct v4l2_subdev *sd, 687 struct v4l2_subdev_pad_config *cfg, 688 struct v4l2_subdev_selection *sel) 689 { 690 struct rkisp1_resizer *rsz = 691 container_of(sd, struct rkisp1_resizer, sd); 692 693 if (sel->target != V4L2_SEL_TGT_CROP || sel->pad == RKISP1_RSZ_PAD_SRC) 694 return -EINVAL; 695 696 dev_dbg(rsz->rkisp1->dev, "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__, 697 sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height); 698 699 mutex_lock(&rsz->ops_lock); 700 rkisp1_rsz_set_sink_crop(rsz, cfg, &sel->r, sel->which); 701 mutex_unlock(&rsz->ops_lock); 702 703 return 0; 704 } 705 706 static const struct media_entity_operations rkisp1_rsz_media_ops = { 707 .link_validate = v4l2_subdev_link_validate, 708 }; 709 710 static const struct v4l2_subdev_pad_ops rkisp1_rsz_pad_ops = { 711 .enum_mbus_code = rkisp1_rsz_enum_mbus_code, 712 .get_selection = rkisp1_rsz_get_selection, 713 .set_selection = rkisp1_rsz_set_selection, 714 .init_cfg = rkisp1_rsz_init_config, 715 .get_fmt = rkisp1_rsz_get_fmt, 716 .set_fmt = rkisp1_rsz_set_fmt, 717 .link_validate = v4l2_subdev_link_validate_default, 718 }; 719 720 /* ---------------------------------------------------------------------------- 721 * Stream operations 722 */ 723 724 static int rkisp1_rsz_s_stream(struct v4l2_subdev *sd, int enable) 725 { 726 struct rkisp1_resizer *rsz = 727 container_of(sd, struct rkisp1_resizer, sd); 728 struct rkisp1_device *rkisp1 = rsz->rkisp1; 729 struct rkisp1_capture *other = &rkisp1->capture_devs[rsz->id ^ 1]; 730 enum rkisp1_shadow_regs_when when = RKISP1_SHADOW_REGS_SYNC; 731 732 if (!enable) { 733 rkisp1_dcrop_disable(rsz, RKISP1_SHADOW_REGS_ASYNC); 734 rkisp1_rsz_disable(rsz, RKISP1_SHADOW_REGS_ASYNC); 735 return 0; 736 } 737 738 if (other->is_streaming) 739 when = RKISP1_SHADOW_REGS_ASYNC; 740 741 mutex_lock(&rsz->ops_lock); 742 rkisp1_rsz_config(rsz, when); 743 rkisp1_dcrop_config(rsz); 744 745 mutex_unlock(&rsz->ops_lock); 746 return 0; 747 } 748 749 static const struct v4l2_subdev_video_ops rkisp1_rsz_video_ops = { 750 .s_stream = rkisp1_rsz_s_stream, 751 }; 752 753 static const struct v4l2_subdev_ops rkisp1_rsz_ops = { 754 .video = &rkisp1_rsz_video_ops, 755 .pad = &rkisp1_rsz_pad_ops, 756 }; 757 758 static void rkisp1_rsz_unregister(struct rkisp1_resizer *rsz) 759 { 760 v4l2_device_unregister_subdev(&rsz->sd); 761 media_entity_cleanup(&rsz->sd.entity); 762 } 763 764 static int rkisp1_rsz_register(struct rkisp1_resizer *rsz) 765 { 766 static const char * const dev_names[] = { 767 RKISP1_RSZ_MP_DEV_NAME, 768 RKISP1_RSZ_SP_DEV_NAME 769 }; 770 struct media_pad *pads = rsz->pads; 771 struct v4l2_subdev *sd = &rsz->sd; 772 int ret; 773 774 if (rsz->id == RKISP1_SELFPATH) 775 rsz->config = &rkisp1_rsz_config_sp; 776 else 777 rsz->config = &rkisp1_rsz_config_mp; 778 779 v4l2_subdev_init(sd, &rkisp1_rsz_ops); 780 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 781 sd->entity.ops = &rkisp1_rsz_media_ops; 782 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER; 783 sd->owner = THIS_MODULE; 784 strscpy(sd->name, dev_names[rsz->id], sizeof(sd->name)); 785 786 pads[RKISP1_RSZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK | 787 MEDIA_PAD_FL_MUST_CONNECT; 788 pads[RKISP1_RSZ_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE | 789 MEDIA_PAD_FL_MUST_CONNECT; 790 791 rsz->pixel_enc = RKISP1_DEF_PIXEL_ENC; 792 793 mutex_init(&rsz->ops_lock); 794 ret = media_entity_pads_init(&sd->entity, RKISP1_RSZ_PAD_MAX, pads); 795 if (ret) 796 return ret; 797 798 ret = v4l2_device_register_subdev(&rsz->rkisp1->v4l2_dev, sd); 799 if (ret) { 800 dev_err(sd->dev, "Failed to register resizer subdev\n"); 801 goto err_cleanup_media_entity; 802 } 803 804 rkisp1_rsz_init_config(sd, rsz->pad_cfg); 805 return 0; 806 807 err_cleanup_media_entity: 808 media_entity_cleanup(&sd->entity); 809 810 return ret; 811 } 812 813 int rkisp1_resizer_devs_register(struct rkisp1_device *rkisp1) 814 { 815 struct rkisp1_resizer *rsz; 816 unsigned int i, j; 817 int ret; 818 819 for (i = 0; i < ARRAY_SIZE(rkisp1->resizer_devs); i++) { 820 rsz = &rkisp1->resizer_devs[i]; 821 rsz->rkisp1 = rkisp1; 822 rsz->id = i; 823 ret = rkisp1_rsz_register(rsz); 824 if (ret) 825 goto err_unreg_resizer_devs; 826 } 827 828 return 0; 829 830 err_unreg_resizer_devs: 831 for (j = 0; j < i; j++) { 832 rsz = &rkisp1->resizer_devs[j]; 833 rkisp1_rsz_unregister(rsz); 834 } 835 836 return ret; 837 } 838 839 void rkisp1_resizer_devs_unregister(struct rkisp1_device *rkisp1) 840 { 841 struct rkisp1_resizer *mp = &rkisp1->resizer_devs[RKISP1_MAINPATH]; 842 struct rkisp1_resizer *sp = &rkisp1->resizer_devs[RKISP1_SELFPATH]; 843 844 rkisp1_rsz_unregister(mp); 845 rkisp1_rsz_unregister(sp); 846 } 847