1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Contains the driver implementation for the V4L2 stateless interface. 4 */ 5 6 #include <linux/debugfs.h> 7 #include <linux/font.h> 8 #include <media/v4l2-event.h> 9 #include <media/v4l2-ioctl.h> 10 #include <media/videobuf2-vmalloc.h> 11 #include <media/videobuf2-v4l2.h> 12 13 #include "visl-video.h" 14 15 #include "visl.h" 16 #include "visl-debugfs.h" 17 18 #define MIN_CODED_SZ (1024U * 256U) 19 20 static void visl_set_current_codec(struct visl_ctx *ctx) 21 { 22 u32 fourcc = ctx->coded_fmt.fmt.pix_mp.pixelformat; 23 24 switch (fourcc) { 25 case V4L2_PIX_FMT_FWHT_STATELESS: 26 ctx->current_codec = VISL_CODEC_FWHT; 27 break; 28 case V4L2_PIX_FMT_MPEG2_SLICE: 29 ctx->current_codec = VISL_CODEC_MPEG2; 30 break; 31 case V4L2_PIX_FMT_VP8_FRAME: 32 ctx->current_codec = VISL_CODEC_VP8; 33 break; 34 case V4L2_PIX_FMT_VP9_FRAME: 35 ctx->current_codec = VISL_CODEC_VP9; 36 break; 37 case V4L2_PIX_FMT_H264_SLICE: 38 ctx->current_codec = VISL_CODEC_H264; 39 break; 40 case V4L2_PIX_FMT_HEVC_SLICE: 41 ctx->current_codec = VISL_CODEC_HEVC; 42 break; 43 case V4L2_PIX_FMT_AV1_FRAME: 44 ctx->current_codec = VISL_CODEC_AV1; 45 break; 46 default: 47 dprintk(ctx->dev, "Warning: unsupported fourcc: %d\n", fourcc); 48 ctx->current_codec = VISL_CODEC_NONE; 49 break; 50 } 51 } 52 53 static void visl_print_fmt(struct visl_ctx *ctx, const struct v4l2_format *f) 54 { 55 const struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 56 u32 i; 57 58 dprintk(ctx->dev, "width: %d\n", pix_mp->width); 59 dprintk(ctx->dev, "height: %d\n", pix_mp->height); 60 dprintk(ctx->dev, "pixelformat: %c%c%c%c\n", 61 pix_mp->pixelformat, 62 (pix_mp->pixelformat >> 8) & 0xff, 63 (pix_mp->pixelformat >> 16) & 0xff, 64 (pix_mp->pixelformat >> 24) & 0xff); 65 66 dprintk(ctx->dev, "field: %d\n", pix_mp->field); 67 dprintk(ctx->dev, "colorspace: %d\n", pix_mp->colorspace); 68 dprintk(ctx->dev, "num_planes: %d\n", pix_mp->num_planes); 69 dprintk(ctx->dev, "flags: %d\n", pix_mp->flags); 70 dprintk(ctx->dev, "quantization: %d\n", pix_mp->quantization); 71 dprintk(ctx->dev, "xfer_func: %d\n", pix_mp->xfer_func); 72 73 for (i = 0; i < pix_mp->num_planes; i++) { 74 dprintk(ctx->dev, 75 "plane[%d]: sizeimage: %d\n", i, pix_mp->plane_fmt[i].sizeimage); 76 dprintk(ctx->dev, 77 "plane[%d]: bytesperline: %d\n", i, pix_mp->plane_fmt[i].bytesperline); 78 } 79 } 80 81 static int visl_tpg_init(struct visl_ctx *ctx) 82 { 83 const struct font_desc *font; 84 const char *font_name = "VGA8x16"; 85 int ret; 86 u32 width = ctx->decoded_fmt.fmt.pix_mp.width; 87 u32 height = ctx->decoded_fmt.fmt.pix_mp.height; 88 struct v4l2_pix_format_mplane *f = &ctx->decoded_fmt.fmt.pix_mp; 89 90 tpg_free(&ctx->tpg); 91 92 font = find_font(font_name); 93 if (font) { 94 tpg_init(&ctx->tpg, width, height); 95 96 ret = tpg_alloc(&ctx->tpg, width); 97 if (ret) 98 goto err_alloc; 99 100 tpg_set_font(font->data); 101 ret = tpg_s_fourcc(&ctx->tpg, 102 f->pixelformat); 103 104 if (!ret) 105 goto err_fourcc; 106 107 tpg_reset_source(&ctx->tpg, width, height, f->field); 108 109 tpg_s_pattern(&ctx->tpg, TPG_PAT_75_COLORBAR); 110 111 tpg_s_field(&ctx->tpg, f->field, false); 112 tpg_s_colorspace(&ctx->tpg, f->colorspace); 113 tpg_s_ycbcr_enc(&ctx->tpg, f->ycbcr_enc); 114 tpg_s_quantization(&ctx->tpg, f->quantization); 115 tpg_s_xfer_func(&ctx->tpg, f->xfer_func); 116 } else { 117 v4l2_err(&ctx->dev->v4l2_dev, 118 "Font %s not found\n", font_name); 119 120 return -EINVAL; 121 } 122 123 dprintk(ctx->dev, "Initialized the V4L2 test pattern generator, w=%d, h=%d, max_w=%d\n", 124 width, height, width); 125 126 return 0; 127 err_alloc: 128 return ret; 129 err_fourcc: 130 tpg_free(&ctx->tpg); 131 return ret; 132 } 133 134 static const u32 visl_decoded_fmts[] = { 135 V4L2_PIX_FMT_NV12, 136 V4L2_PIX_FMT_YUV420, 137 }; 138 139 const struct visl_coded_format_desc visl_coded_fmts[] = { 140 { 141 .pixelformat = V4L2_PIX_FMT_FWHT_STATELESS, 142 .frmsize = { 143 .min_width = 640, 144 .max_width = 4096, 145 .step_width = 1, 146 .min_height = 360, 147 .max_height = 2160, 148 .step_height = 1, 149 }, 150 .ctrls = &visl_fwht_ctrls, 151 .num_decoded_fmts = ARRAY_SIZE(visl_decoded_fmts), 152 .decoded_fmts = visl_decoded_fmts, 153 }, 154 { 155 .pixelformat = V4L2_PIX_FMT_MPEG2_SLICE, 156 .frmsize = { 157 .min_width = 16, 158 .max_width = 1920, 159 .step_width = 1, 160 .min_height = 16, 161 .max_height = 1152, 162 .step_height = 1, 163 }, 164 .ctrls = &visl_mpeg2_ctrls, 165 .num_decoded_fmts = ARRAY_SIZE(visl_decoded_fmts), 166 .decoded_fmts = visl_decoded_fmts, 167 }, 168 { 169 .pixelformat = V4L2_PIX_FMT_VP8_FRAME, 170 .frmsize = { 171 .min_width = 64, 172 .max_width = 16383, 173 .step_width = 1, 174 .min_height = 64, 175 .max_height = 16383, 176 .step_height = 1, 177 }, 178 .ctrls = &visl_vp8_ctrls, 179 .num_decoded_fmts = ARRAY_SIZE(visl_decoded_fmts), 180 .decoded_fmts = visl_decoded_fmts, 181 }, 182 { 183 .pixelformat = V4L2_PIX_FMT_VP9_FRAME, 184 .frmsize = { 185 .min_width = 64, 186 .max_width = 8192, 187 .step_width = 1, 188 .min_height = 64, 189 .max_height = 4352, 190 .step_height = 1, 191 }, 192 .ctrls = &visl_vp9_ctrls, 193 .num_decoded_fmts = ARRAY_SIZE(visl_decoded_fmts), 194 .decoded_fmts = visl_decoded_fmts, 195 }, 196 { 197 .pixelformat = V4L2_PIX_FMT_H264_SLICE, 198 .frmsize = { 199 .min_width = 64, 200 .max_width = 4096, 201 .step_width = 1, 202 .min_height = 64, 203 .max_height = 2304, 204 .step_height = 1, 205 }, 206 .ctrls = &visl_h264_ctrls, 207 .num_decoded_fmts = ARRAY_SIZE(visl_decoded_fmts), 208 .decoded_fmts = visl_decoded_fmts, 209 }, 210 { 211 .pixelformat = V4L2_PIX_FMT_HEVC_SLICE, 212 .frmsize = { 213 .min_width = 64, 214 .max_width = 4096, 215 .step_width = 1, 216 .min_height = 64, 217 .max_height = 2304, 218 .step_height = 1, 219 }, 220 .ctrls = &visl_hevc_ctrls, 221 .num_decoded_fmts = ARRAY_SIZE(visl_decoded_fmts), 222 .decoded_fmts = visl_decoded_fmts, 223 }, 224 { 225 .pixelformat = V4L2_PIX_FMT_AV1_FRAME, 226 .frmsize = { 227 .min_width = 64, 228 .max_width = 4096, 229 .step_width = 1, 230 .min_height = 64, 231 .max_height = 2304, 232 .step_height = 1, 233 }, 234 .ctrls = &visl_av1_ctrls, 235 .num_decoded_fmts = ARRAY_SIZE(visl_decoded_fmts), 236 .decoded_fmts = visl_decoded_fmts, 237 }, 238 239 }; 240 241 const size_t num_coded_fmts = ARRAY_SIZE(visl_coded_fmts); 242 243 static const struct visl_coded_format_desc* 244 visl_find_coded_fmt_desc(u32 fourcc) 245 { 246 unsigned int i; 247 248 for (i = 0; i < ARRAY_SIZE(visl_coded_fmts); i++) { 249 if (visl_coded_fmts[i].pixelformat == fourcc) 250 return &visl_coded_fmts[i]; 251 } 252 253 return NULL; 254 } 255 256 static void visl_init_fmt(struct v4l2_format *f, u32 fourcc) 257 { memset(f, 0, sizeof(*f)); 258 f->fmt.pix_mp.pixelformat = fourcc; 259 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 260 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; 261 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 262 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 263 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 264 } 265 266 static void visl_reset_coded_fmt(struct visl_ctx *ctx) 267 { 268 struct v4l2_format *f = &ctx->coded_fmt; 269 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 270 271 ctx->coded_format_desc = &visl_coded_fmts[0]; 272 visl_init_fmt(f, ctx->coded_format_desc->pixelformat); 273 274 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 275 f->fmt.pix_mp.width = ctx->coded_format_desc->frmsize.min_width; 276 f->fmt.pix_mp.height = ctx->coded_format_desc->frmsize.min_height; 277 278 pix_mp->num_planes = 1; 279 pix_mp->plane_fmt[0].sizeimage = pix_mp->width * pix_mp->height * 8; 280 281 dprintk(ctx->dev, "OUTPUT format was set to:\n"); 282 visl_print_fmt(ctx, &ctx->coded_fmt); 283 284 visl_set_current_codec(ctx); 285 } 286 287 static int visl_reset_decoded_fmt(struct visl_ctx *ctx) 288 { 289 struct v4l2_format *f = &ctx->decoded_fmt; 290 u32 decoded_fmt = ctx->coded_format_desc[0].decoded_fmts[0]; 291 292 visl_init_fmt(f, decoded_fmt); 293 294 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 295 296 v4l2_fill_pixfmt_mp(&f->fmt.pix_mp, 297 ctx->coded_format_desc->decoded_fmts[0], 298 ctx->coded_fmt.fmt.pix_mp.width, 299 ctx->coded_fmt.fmt.pix_mp.height); 300 301 dprintk(ctx->dev, "CAPTURE format was set to:\n"); 302 visl_print_fmt(ctx, &ctx->decoded_fmt); 303 304 return visl_tpg_init(ctx); 305 } 306 307 int visl_set_default_format(struct visl_ctx *ctx) 308 { 309 visl_reset_coded_fmt(ctx); 310 return visl_reset_decoded_fmt(ctx); 311 } 312 313 static struct visl_q_data *get_q_data(struct visl_ctx *ctx, 314 enum v4l2_buf_type type) 315 { 316 switch (type) { 317 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 318 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 319 return &ctx->q_data[V4L2_M2M_SRC]; 320 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 321 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 322 return &ctx->q_data[V4L2_M2M_DST]; 323 default: 324 break; 325 } 326 return NULL; 327 } 328 329 static int visl_querycap(struct file *file, void *priv, 330 struct v4l2_capability *cap) 331 { 332 strscpy(cap->driver, VISL_NAME, sizeof(cap->driver)); 333 strscpy(cap->card, VISL_NAME, sizeof(cap->card)); 334 snprintf(cap->bus_info, sizeof(cap->bus_info), 335 "platform:%s", VISL_NAME); 336 337 return 0; 338 } 339 340 static int visl_enum_fmt_vid_cap(struct file *file, void *priv, 341 struct v4l2_fmtdesc *f) 342 { 343 struct visl_ctx *ctx = visl_file_to_ctx(file); 344 345 if (f->index >= ctx->coded_format_desc->num_decoded_fmts) 346 return -EINVAL; 347 348 f->pixelformat = ctx->coded_format_desc->decoded_fmts[f->index]; 349 return 0; 350 } 351 352 static int visl_enum_fmt_vid_out(struct file *file, void *priv, 353 struct v4l2_fmtdesc *f) 354 { 355 if (f->index >= ARRAY_SIZE(visl_coded_fmts)) 356 return -EINVAL; 357 358 f->pixelformat = visl_coded_fmts[f->index].pixelformat; 359 return 0; 360 } 361 362 static int visl_g_fmt_vid_cap(struct file *file, void *priv, 363 struct v4l2_format *f) 364 { 365 struct visl_ctx *ctx = visl_file_to_ctx(file); 366 *f = ctx->decoded_fmt; 367 368 return 0; 369 } 370 371 static int visl_g_fmt_vid_out(struct file *file, void *priv, 372 struct v4l2_format *f) 373 { 374 struct visl_ctx *ctx = visl_file_to_ctx(file); 375 376 *f = ctx->coded_fmt; 377 return 0; 378 } 379 380 static int visl_try_fmt_vid_cap(struct file *file, void *priv, 381 struct v4l2_format *f) 382 { 383 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 384 struct visl_ctx *ctx = visl_file_to_ctx(file); 385 const struct visl_coded_format_desc *coded_desc; 386 unsigned int i; 387 388 coded_desc = ctx->coded_format_desc; 389 390 for (i = 0; i < coded_desc->num_decoded_fmts; i++) { 391 if (coded_desc->decoded_fmts[i] == pix_mp->pixelformat) 392 break; 393 } 394 395 if (i == coded_desc->num_decoded_fmts) 396 pix_mp->pixelformat = coded_desc->decoded_fmts[0]; 397 398 v4l2_apply_frmsize_constraints(&pix_mp->width, 399 &pix_mp->height, 400 &coded_desc->frmsize); 401 402 v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, 403 pix_mp->width, pix_mp->height); 404 405 pix_mp->field = V4L2_FIELD_NONE; 406 407 return 0; 408 } 409 410 static int visl_try_fmt_vid_out(struct file *file, void *priv, 411 struct v4l2_format *f) 412 { 413 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 414 const struct visl_coded_format_desc *coded_desc; 415 416 coded_desc = visl_find_coded_fmt_desc(pix_mp->pixelformat); 417 if (!coded_desc) { 418 pix_mp->pixelformat = visl_coded_fmts[0].pixelformat; 419 coded_desc = &visl_coded_fmts[0]; 420 } 421 422 v4l2_apply_frmsize_constraints(&pix_mp->width, 423 &pix_mp->height, 424 &coded_desc->frmsize); 425 426 pix_mp->field = V4L2_FIELD_NONE; 427 pix_mp->num_planes = 1; 428 429 if (pix_mp->plane_fmt[0].sizeimage == 0) 430 pix_mp->plane_fmt[0].sizeimage = max(MIN_CODED_SZ, 431 pix_mp->width * pix_mp->height * 3); 432 433 return 0; 434 } 435 436 static int visl_s_fmt_vid_out(struct file *file, void *priv, 437 struct v4l2_format *f) 438 { 439 struct visl_ctx *ctx = visl_file_to_ctx(file); 440 struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; 441 const struct visl_coded_format_desc *desc; 442 struct vb2_queue *peer_vq; 443 int ret; 444 445 peer_vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 446 if (vb2_is_busy(peer_vq)) 447 return -EBUSY; 448 449 dprintk(ctx->dev, "Trying to set the OUTPUT format to:\n"); 450 visl_print_fmt(ctx, f); 451 452 ret = visl_try_fmt_vid_out(file, priv, f); 453 if (ret) 454 return ret; 455 456 desc = visl_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat); 457 ctx->coded_format_desc = desc; 458 ctx->coded_fmt = *f; 459 460 ret = visl_reset_decoded_fmt(ctx); 461 if (ret) 462 return ret; 463 464 ctx->decoded_fmt.fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 465 ctx->decoded_fmt.fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 466 ctx->decoded_fmt.fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 467 ctx->decoded_fmt.fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 468 469 dprintk(ctx->dev, "OUTPUT format was set to:\n"); 470 visl_print_fmt(ctx, &ctx->coded_fmt); 471 472 visl_set_current_codec(ctx); 473 return 0; 474 } 475 476 static int visl_s_fmt_vid_cap(struct file *file, void *priv, 477 struct v4l2_format *f) 478 { 479 struct visl_ctx *ctx = visl_file_to_ctx(file); 480 int ret; 481 482 dprintk(ctx->dev, "Trying to set the CAPTURE format to:\n"); 483 visl_print_fmt(ctx, f); 484 485 ret = visl_try_fmt_vid_cap(file, priv, f); 486 if (ret) 487 return ret; 488 489 ctx->decoded_fmt = *f; 490 491 dprintk(ctx->dev, "CAPTURE format was set to:\n"); 492 visl_print_fmt(ctx, &ctx->decoded_fmt); 493 494 visl_tpg_init(ctx); 495 return 0; 496 } 497 498 static int visl_enum_framesizes(struct file *file, void *priv, 499 struct v4l2_frmsizeenum *fsize) 500 { 501 const struct visl_coded_format_desc *fmt; 502 struct visl_ctx *ctx = visl_file_to_ctx(file); 503 504 if (fsize->index != 0) 505 return -EINVAL; 506 507 fmt = visl_find_coded_fmt_desc(fsize->pixel_format); 508 if (!fmt) { 509 dprintk(ctx->dev, 510 "Unsupported format for the OUTPUT queue: %d\n", 511 fsize->pixel_format); 512 513 return -EINVAL; 514 } 515 516 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 517 fsize->stepwise = fmt->frmsize; 518 return 0; 519 } 520 521 const struct v4l2_ioctl_ops visl_ioctl_ops = { 522 .vidioc_querycap = visl_querycap, 523 .vidioc_enum_framesizes = visl_enum_framesizes, 524 525 .vidioc_enum_fmt_vid_cap = visl_enum_fmt_vid_cap, 526 .vidioc_g_fmt_vid_cap_mplane = visl_g_fmt_vid_cap, 527 .vidioc_try_fmt_vid_cap_mplane = visl_try_fmt_vid_cap, 528 .vidioc_s_fmt_vid_cap_mplane = visl_s_fmt_vid_cap, 529 530 .vidioc_enum_fmt_vid_out = visl_enum_fmt_vid_out, 531 .vidioc_g_fmt_vid_out_mplane = visl_g_fmt_vid_out, 532 .vidioc_try_fmt_vid_out_mplane = visl_try_fmt_vid_out, 533 .vidioc_s_fmt_vid_out_mplane = visl_s_fmt_vid_out, 534 535 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 536 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 537 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 538 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 539 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 540 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 541 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 542 .vidioc_remove_bufs = v4l2_m2m_ioctl_remove_bufs, 543 544 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 545 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 546 547 .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, 548 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, 549 550 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 551 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 552 }; 553 554 static int visl_queue_setup(struct vb2_queue *vq, 555 unsigned int *nbuffers, 556 unsigned int *num_planes, 557 unsigned int sizes[], 558 struct device *alloc_devs[]) 559 { 560 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 561 struct v4l2_format *f; 562 u32 i; 563 char *qname; 564 565 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { 566 f = &ctx->coded_fmt; 567 qname = "Output"; 568 } else { 569 f = &ctx->decoded_fmt; 570 qname = "Capture"; 571 } 572 573 if (*num_planes) { 574 if (*num_planes != f->fmt.pix_mp.num_planes) 575 return -EINVAL; 576 577 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { 578 if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage) 579 return -EINVAL; 580 } 581 } else { 582 *num_planes = f->fmt.pix_mp.num_planes; 583 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) 584 sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; 585 } 586 587 dprintk(ctx->dev, "%s: %d buffer(s) requested, num_planes=%d.\n", 588 qname, *nbuffers, *num_planes); 589 590 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) 591 dprintk(ctx->dev, "plane[%d].sizeimage=%d\n", 592 i, f->fmt.pix_mp.plane_fmt[i].sizeimage); 593 594 return 0; 595 } 596 597 static void visl_queue_cleanup(struct vb2_queue *vq, u32 state) 598 { 599 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 600 struct vb2_v4l2_buffer *vbuf; 601 602 dprintk(ctx->dev, "Cleaning up queues\n"); 603 for (;;) { 604 if (V4L2_TYPE_IS_OUTPUT(vq->type)) 605 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 606 else 607 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 608 609 if (!vbuf) 610 break; 611 612 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, 613 &ctx->hdl); 614 dprintk(ctx->dev, "Marked request %p as complete\n", 615 vbuf->vb2_buf.req_obj.req); 616 617 v4l2_m2m_buf_done(vbuf, state); 618 dprintk(ctx->dev, 619 "Marked buffer %llu as done, state is %d\n", 620 vbuf->vb2_buf.timestamp, 621 state); 622 } 623 } 624 625 static int visl_buf_out_validate(struct vb2_buffer *vb) 626 { 627 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 628 629 vbuf->field = V4L2_FIELD_NONE; 630 return 0; 631 } 632 633 static int visl_buf_prepare(struct vb2_buffer *vb) 634 { 635 struct vb2_queue *vq = vb->vb2_queue; 636 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 637 u32 plane_sz = vb2_plane_size(vb, 0); 638 struct v4l2_pix_format *pix_fmt; 639 640 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { 641 pix_fmt = &ctx->coded_fmt.fmt.pix; 642 } else { 643 pix_fmt = &ctx->decoded_fmt.fmt.pix; 644 vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); 645 } 646 647 if (plane_sz < pix_fmt->sizeimage) { 648 v4l2_err(&ctx->dev->v4l2_dev, "plane[0] size is %d, sizeimage is %d\n", 649 plane_sz, pix_fmt->sizeimage); 650 return -EINVAL; 651 } 652 653 return 0; 654 } 655 656 static int visl_start_streaming(struct vb2_queue *vq, unsigned int count) 657 { 658 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 659 struct visl_q_data *q_data = get_q_data(ctx, vq->type); 660 int rc = 0; 661 662 if (!q_data) { 663 rc = -EINVAL; 664 goto err; 665 } 666 667 q_data->sequence = 0; 668 669 if (V4L2_TYPE_IS_CAPTURE(vq->type)) { 670 ctx->capture_streamon_jiffies = get_jiffies_64(); 671 return 0; 672 } 673 674 if (WARN_ON(!ctx->coded_format_desc)) { 675 rc = -EINVAL; 676 goto err; 677 } 678 679 return 0; 680 681 err: 682 visl_queue_cleanup(vq, VB2_BUF_STATE_QUEUED); 683 return rc; 684 } 685 686 static void visl_stop_streaming(struct vb2_queue *vq) 687 { 688 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 689 690 dprintk(ctx->dev, "Stop streaming\n"); 691 visl_queue_cleanup(vq, VB2_BUF_STATE_ERROR); 692 693 if (!keep_bitstream_buffers) 694 visl_debugfs_clear_bitstream(ctx->dev); 695 } 696 697 static void visl_buf_queue(struct vb2_buffer *vb) 698 { 699 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 700 struct visl_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 701 702 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 703 } 704 705 static void visl_buf_request_complete(struct vb2_buffer *vb) 706 { 707 struct visl_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 708 709 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl); 710 } 711 712 static const struct vb2_ops visl_qops = { 713 .queue_setup = visl_queue_setup, 714 .buf_out_validate = visl_buf_out_validate, 715 .buf_prepare = visl_buf_prepare, 716 .buf_queue = visl_buf_queue, 717 .start_streaming = visl_start_streaming, 718 .stop_streaming = visl_stop_streaming, 719 .wait_prepare = vb2_ops_wait_prepare, 720 .wait_finish = vb2_ops_wait_finish, 721 .buf_request_complete = visl_buf_request_complete, 722 }; 723 724 int visl_queue_init(void *priv, struct vb2_queue *src_vq, 725 struct vb2_queue *dst_vq) 726 { 727 struct visl_ctx *ctx = priv; 728 int ret; 729 730 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 731 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 732 src_vq->drv_priv = ctx; 733 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 734 src_vq->ops = &visl_qops; 735 src_vq->mem_ops = &vb2_vmalloc_memops; 736 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 737 src_vq->lock = &ctx->vb_mutex; 738 src_vq->supports_requests = true; 739 src_vq->subsystem_flags |= VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF; 740 741 ret = vb2_queue_init(src_vq); 742 if (ret) 743 return ret; 744 745 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 746 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 747 dst_vq->drv_priv = ctx; 748 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 749 dst_vq->ops = &visl_qops; 750 dst_vq->mem_ops = &vb2_vmalloc_memops; 751 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 752 dst_vq->lock = &ctx->vb_mutex; 753 754 return vb2_queue_init(dst_vq); 755 } 756 757 int visl_request_validate(struct media_request *req) 758 { 759 struct media_request_object *obj; 760 struct visl_ctx *ctx = NULL; 761 unsigned int count; 762 763 list_for_each_entry(obj, &req->objects, list) { 764 struct vb2_buffer *vb; 765 766 if (vb2_request_object_is_buffer(obj)) { 767 vb = container_of(obj, struct vb2_buffer, req_obj); 768 ctx = vb2_get_drv_priv(vb->vb2_queue); 769 770 break; 771 } 772 } 773 774 if (!ctx) 775 return -ENOENT; 776 777 count = vb2_request_buffer_cnt(req); 778 if (!count) { 779 v4l2_err(&ctx->dev->v4l2_dev, 780 "No buffer was provided with the request\n"); 781 return -ENOENT; 782 } else if (count > 1) { 783 v4l2_err(&ctx->dev->v4l2_dev, 784 "More than one buffer was provided with the request\n"); 785 return -EINVAL; 786 } 787 788 return vb2_request_validate(req); 789 } 790