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 543 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 544 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 545 546 .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, 547 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, 548 549 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 550 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 551 }; 552 553 static int visl_queue_setup(struct vb2_queue *vq, 554 unsigned int *nbuffers, 555 unsigned int *num_planes, 556 unsigned int sizes[], 557 struct device *alloc_devs[]) 558 { 559 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 560 struct v4l2_format *f; 561 u32 i; 562 char *qname; 563 564 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { 565 f = &ctx->coded_fmt; 566 qname = "Output"; 567 } else { 568 f = &ctx->decoded_fmt; 569 qname = "Capture"; 570 } 571 572 if (*num_planes) { 573 if (*num_planes != f->fmt.pix_mp.num_planes) 574 return -EINVAL; 575 576 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { 577 if (sizes[i] < f->fmt.pix_mp.plane_fmt[i].sizeimage) 578 return -EINVAL; 579 } 580 } else { 581 *num_planes = f->fmt.pix_mp.num_planes; 582 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) 583 sizes[i] = f->fmt.pix_mp.plane_fmt[i].sizeimage; 584 } 585 586 dprintk(ctx->dev, "%s: %d buffer(s) requested, num_planes=%d.\n", 587 qname, *nbuffers, *num_planes); 588 589 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) 590 dprintk(ctx->dev, "plane[%d].sizeimage=%d\n", 591 i, f->fmt.pix_mp.plane_fmt[i].sizeimage); 592 593 return 0; 594 } 595 596 static void visl_queue_cleanup(struct vb2_queue *vq, u32 state) 597 { 598 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 599 struct vb2_v4l2_buffer *vbuf; 600 601 dprintk(ctx->dev, "Cleaning up queues\n"); 602 for (;;) { 603 if (V4L2_TYPE_IS_OUTPUT(vq->type)) 604 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 605 else 606 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 607 608 if (!vbuf) 609 break; 610 611 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, 612 &ctx->hdl); 613 dprintk(ctx->dev, "Marked request %p as complete\n", 614 vbuf->vb2_buf.req_obj.req); 615 616 v4l2_m2m_buf_done(vbuf, state); 617 dprintk(ctx->dev, 618 "Marked buffer %llu as done, state is %d\n", 619 vbuf->vb2_buf.timestamp, 620 state); 621 } 622 } 623 624 static int visl_buf_out_validate(struct vb2_buffer *vb) 625 { 626 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 627 628 vbuf->field = V4L2_FIELD_NONE; 629 return 0; 630 } 631 632 static int visl_buf_prepare(struct vb2_buffer *vb) 633 { 634 struct vb2_queue *vq = vb->vb2_queue; 635 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 636 u32 plane_sz = vb2_plane_size(vb, 0); 637 struct v4l2_pix_format *pix_fmt; 638 639 if (V4L2_TYPE_IS_OUTPUT(vq->type)) { 640 pix_fmt = &ctx->coded_fmt.fmt.pix; 641 } else { 642 pix_fmt = &ctx->decoded_fmt.fmt.pix; 643 vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); 644 } 645 646 if (plane_sz < pix_fmt->sizeimage) { 647 v4l2_err(&ctx->dev->v4l2_dev, "plane[0] size is %d, sizeimage is %d\n", 648 plane_sz, pix_fmt->sizeimage); 649 return -EINVAL; 650 } 651 652 return 0; 653 } 654 655 static int visl_start_streaming(struct vb2_queue *vq, unsigned int count) 656 { 657 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 658 struct visl_q_data *q_data = get_q_data(ctx, vq->type); 659 int rc = 0; 660 661 if (!q_data) { 662 rc = -EINVAL; 663 goto err; 664 } 665 666 q_data->sequence = 0; 667 668 if (V4L2_TYPE_IS_CAPTURE(vq->type)) { 669 ctx->capture_streamon_jiffies = get_jiffies_64(); 670 return 0; 671 } 672 673 if (WARN_ON(!ctx->coded_format_desc)) { 674 rc = -EINVAL; 675 goto err; 676 } 677 678 return 0; 679 680 err: 681 visl_queue_cleanup(vq, VB2_BUF_STATE_QUEUED); 682 return rc; 683 } 684 685 static void visl_stop_streaming(struct vb2_queue *vq) 686 { 687 struct visl_ctx *ctx = vb2_get_drv_priv(vq); 688 689 dprintk(ctx->dev, "Stop streaming\n"); 690 visl_queue_cleanup(vq, VB2_BUF_STATE_ERROR); 691 692 if (!keep_bitstream_buffers) 693 visl_debugfs_clear_bitstream(ctx->dev); 694 } 695 696 static void visl_buf_queue(struct vb2_buffer *vb) 697 { 698 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 699 struct visl_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 700 701 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 702 } 703 704 static void visl_buf_request_complete(struct vb2_buffer *vb) 705 { 706 struct visl_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 707 708 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl); 709 } 710 711 static const struct vb2_ops visl_qops = { 712 .queue_setup = visl_queue_setup, 713 .buf_out_validate = visl_buf_out_validate, 714 .buf_prepare = visl_buf_prepare, 715 .buf_queue = visl_buf_queue, 716 .start_streaming = visl_start_streaming, 717 .stop_streaming = visl_stop_streaming, 718 .wait_prepare = vb2_ops_wait_prepare, 719 .wait_finish = vb2_ops_wait_finish, 720 .buf_request_complete = visl_buf_request_complete, 721 }; 722 723 int visl_queue_init(void *priv, struct vb2_queue *src_vq, 724 struct vb2_queue *dst_vq) 725 { 726 struct visl_ctx *ctx = priv; 727 int ret; 728 729 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 730 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 731 src_vq->drv_priv = ctx; 732 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 733 src_vq->ops = &visl_qops; 734 src_vq->mem_ops = &vb2_vmalloc_memops; 735 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 736 src_vq->lock = &ctx->vb_mutex; 737 src_vq->supports_requests = true; 738 src_vq->subsystem_flags |= VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF; 739 740 ret = vb2_queue_init(src_vq); 741 if (ret) 742 return ret; 743 744 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 745 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 746 dst_vq->drv_priv = ctx; 747 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 748 dst_vq->ops = &visl_qops; 749 dst_vq->mem_ops = &vb2_vmalloc_memops; 750 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 751 dst_vq->lock = &ctx->vb_mutex; 752 753 return vb2_queue_init(dst_vq); 754 } 755 756 int visl_request_validate(struct media_request *req) 757 { 758 struct media_request_object *obj; 759 struct visl_ctx *ctx = NULL; 760 unsigned int count; 761 762 list_for_each_entry(obj, &req->objects, list) { 763 struct vb2_buffer *vb; 764 765 if (vb2_request_object_is_buffer(obj)) { 766 vb = container_of(obj, struct vb2_buffer, req_obj); 767 ctx = vb2_get_drv_priv(vb->vb2_queue); 768 769 break; 770 } 771 } 772 773 if (!ctx) 774 return -ENOENT; 775 776 count = vb2_request_buffer_cnt(req); 777 if (!count) { 778 v4l2_err(&ctx->dev->v4l2_dev, 779 "No buffer was provided with the request\n"); 780 return -ENOENT; 781 } else if (count > 1) { 782 v4l2_err(&ctx->dev->v4l2_dev, 783 "More than one buffer was provided with the request\n"); 784 return -EINVAL; 785 } 786 787 return vb2_request_validate(req); 788 } 789