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