1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2018 BayLibre, SAS 4 * Author: Maxime Jourdan <mjourdan@baylibre.com> 5 */ 6 7 #include <linux/of_device.h> 8 #include <linux/clk.h> 9 #include <linux/io.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/mfd/syscon.h> 13 #include <linux/slab.h> 14 #include <linux/interrupt.h> 15 #include <linux/kthread.h> 16 #include <media/v4l2-ioctl.h> 17 #include <media/v4l2-event.h> 18 #include <media/v4l2-ctrls.h> 19 #include <media/v4l2-mem2mem.h> 20 #include <media/v4l2-dev.h> 21 #include <media/videobuf2-dma-contig.h> 22 23 #include "vdec.h" 24 #include "esparser.h" 25 #include "vdec_helpers.h" 26 27 struct dummy_buf { 28 struct vb2_v4l2_buffer vb; 29 struct list_head list; 30 }; 31 32 /* 16 MiB for parsed bitstream swap exchange */ 33 #define SIZE_VIFIFO SZ_16M 34 35 static u32 get_output_size(u32 width, u32 height) 36 { 37 return ALIGN(width * height, SZ_64K); 38 } 39 40 u32 amvdec_get_output_size(struct amvdec_session *sess) 41 { 42 return get_output_size(sess->width, sess->height); 43 } 44 EXPORT_SYMBOL_GPL(amvdec_get_output_size); 45 46 static int vdec_codec_needs_recycle(struct amvdec_session *sess) 47 { 48 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; 49 50 return codec_ops->can_recycle && codec_ops->recycle; 51 } 52 53 static int vdec_recycle_thread(void *data) 54 { 55 struct amvdec_session *sess = data; 56 struct amvdec_core *core = sess->core; 57 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; 58 struct amvdec_buffer *tmp, *n; 59 60 while (!kthread_should_stop()) { 61 mutex_lock(&sess->bufs_recycle_lock); 62 list_for_each_entry_safe(tmp, n, &sess->bufs_recycle, list) { 63 if (!codec_ops->can_recycle(core)) 64 break; 65 66 codec_ops->recycle(core, tmp->vb->index); 67 list_del(&tmp->list); 68 kfree(tmp); 69 } 70 mutex_unlock(&sess->bufs_recycle_lock); 71 72 usleep_range(5000, 10000); 73 } 74 75 return 0; 76 } 77 78 static int vdec_poweron(struct amvdec_session *sess) 79 { 80 int ret; 81 struct amvdec_ops *vdec_ops = sess->fmt_out->vdec_ops; 82 83 ret = clk_prepare_enable(sess->core->dos_parser_clk); 84 if (ret) 85 return ret; 86 87 ret = clk_prepare_enable(sess->core->dos_clk); 88 if (ret) 89 goto disable_dos_parser; 90 91 ret = vdec_ops->start(sess); 92 if (ret) 93 goto disable_dos; 94 95 esparser_power_up(sess); 96 97 return 0; 98 99 disable_dos: 100 clk_disable_unprepare(sess->core->dos_clk); 101 disable_dos_parser: 102 clk_disable_unprepare(sess->core->dos_parser_clk); 103 104 return ret; 105 } 106 107 static void vdec_wait_inactive(struct amvdec_session *sess) 108 { 109 /* We consider 50ms with no IRQ to be inactive. */ 110 while (time_is_after_jiffies64(sess->last_irq_jiffies + 111 msecs_to_jiffies(50))) 112 msleep(25); 113 } 114 115 static void vdec_poweroff(struct amvdec_session *sess) 116 { 117 struct amvdec_ops *vdec_ops = sess->fmt_out->vdec_ops; 118 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; 119 120 sess->should_stop = 1; 121 vdec_wait_inactive(sess); 122 if (codec_ops->drain) 123 codec_ops->drain(sess); 124 125 vdec_ops->stop(sess); 126 clk_disable_unprepare(sess->core->dos_clk); 127 clk_disable_unprepare(sess->core->dos_parser_clk); 128 } 129 130 static void 131 vdec_queue_recycle(struct amvdec_session *sess, struct vb2_buffer *vb) 132 { 133 struct amvdec_buffer *new_buf; 134 135 new_buf = kmalloc(sizeof(*new_buf), GFP_KERNEL); 136 if (!new_buf) 137 return; 138 new_buf->vb = vb; 139 140 mutex_lock(&sess->bufs_recycle_lock); 141 list_add_tail(&new_buf->list, &sess->bufs_recycle); 142 mutex_unlock(&sess->bufs_recycle_lock); 143 } 144 145 static void vdec_m2m_device_run(void *priv) 146 { 147 struct amvdec_session *sess = priv; 148 149 schedule_work(&sess->esparser_queue_work); 150 } 151 152 static void vdec_m2m_job_abort(void *priv) 153 { 154 struct amvdec_session *sess = priv; 155 156 v4l2_m2m_job_finish(sess->m2m_dev, sess->m2m_ctx); 157 } 158 159 static const struct v4l2_m2m_ops vdec_m2m_ops = { 160 .device_run = vdec_m2m_device_run, 161 .job_abort = vdec_m2m_job_abort, 162 }; 163 164 static void process_num_buffers(struct vb2_queue *q, 165 struct amvdec_session *sess, 166 unsigned int *num_buffers, 167 bool is_reqbufs) 168 { 169 const struct amvdec_format *fmt_out = sess->fmt_out; 170 unsigned int buffers_total = q->num_buffers + *num_buffers; 171 172 if (is_reqbufs && buffers_total < fmt_out->min_buffers) 173 *num_buffers = fmt_out->min_buffers - q->num_buffers; 174 if (buffers_total > fmt_out->max_buffers) 175 *num_buffers = fmt_out->max_buffers - q->num_buffers; 176 177 /* We need to program the complete CAPTURE buffer list 178 * in registers during start_streaming, and the firmwares 179 * are free to choose any of them to write frames to. As such, 180 * we need all of them to be queued into the driver 181 */ 182 sess->num_dst_bufs = q->num_buffers + *num_buffers; 183 q->min_buffers_needed = max(fmt_out->min_buffers, sess->num_dst_bufs); 184 } 185 186 static int vdec_queue_setup(struct vb2_queue *q, unsigned int *num_buffers, 187 unsigned int *num_planes, unsigned int sizes[], 188 struct device *alloc_devs[]) 189 { 190 struct amvdec_session *sess = vb2_get_drv_priv(q); 191 u32 output_size = amvdec_get_output_size(sess); 192 193 if (*num_planes) { 194 switch (q->type) { 195 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 196 if (*num_planes != 1 || sizes[0] < output_size) 197 return -EINVAL; 198 break; 199 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 200 switch (sess->pixfmt_cap) { 201 case V4L2_PIX_FMT_NV12M: 202 if (*num_planes != 2 || 203 sizes[0] < output_size || 204 sizes[1] < output_size / 2) 205 return -EINVAL; 206 break; 207 case V4L2_PIX_FMT_YUV420M: 208 if (*num_planes != 3 || 209 sizes[0] < output_size || 210 sizes[1] < output_size / 4 || 211 sizes[2] < output_size / 4) 212 return -EINVAL; 213 break; 214 default: 215 return -EINVAL; 216 } 217 218 process_num_buffers(q, sess, num_buffers, false); 219 break; 220 } 221 222 return 0; 223 } 224 225 switch (q->type) { 226 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 227 sizes[0] = amvdec_get_output_size(sess); 228 *num_planes = 1; 229 break; 230 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 231 switch (sess->pixfmt_cap) { 232 case V4L2_PIX_FMT_NV12M: 233 sizes[0] = output_size; 234 sizes[1] = output_size / 2; 235 *num_planes = 2; 236 break; 237 case V4L2_PIX_FMT_YUV420M: 238 sizes[0] = output_size; 239 sizes[1] = output_size / 4; 240 sizes[2] = output_size / 4; 241 *num_planes = 3; 242 break; 243 default: 244 return -EINVAL; 245 } 246 247 process_num_buffers(q, sess, num_buffers, true); 248 break; 249 default: 250 return -EINVAL; 251 } 252 253 return 0; 254 } 255 256 static void vdec_vb2_buf_queue(struct vb2_buffer *vb) 257 { 258 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 259 struct amvdec_session *sess = vb2_get_drv_priv(vb->vb2_queue); 260 struct v4l2_m2m_ctx *m2m_ctx = sess->m2m_ctx; 261 262 v4l2_m2m_buf_queue(m2m_ctx, vbuf); 263 264 if (!sess->streamon_out || !sess->streamon_cap) 265 return; 266 267 if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 268 vdec_codec_needs_recycle(sess)) 269 vdec_queue_recycle(sess, vb); 270 271 schedule_work(&sess->esparser_queue_work); 272 } 273 274 static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) 275 { 276 struct amvdec_session *sess = vb2_get_drv_priv(q); 277 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; 278 struct amvdec_core *core = sess->core; 279 struct vb2_v4l2_buffer *buf; 280 int ret; 281 282 if (core->cur_sess && core->cur_sess != sess) { 283 ret = -EBUSY; 284 goto bufs_done; 285 } 286 287 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 288 sess->streamon_out = 1; 289 else 290 sess->streamon_cap = 1; 291 292 if (!sess->streamon_out || !sess->streamon_cap) 293 return 0; 294 295 if (sess->status == STATUS_NEEDS_RESUME && 296 q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 297 codec_ops->resume(sess); 298 sess->status = STATUS_RUNNING; 299 return 0; 300 } 301 302 sess->vififo_size = SIZE_VIFIFO; 303 sess->vififo_vaddr = 304 dma_alloc_coherent(sess->core->dev, sess->vififo_size, 305 &sess->vififo_paddr, GFP_KERNEL); 306 if (!sess->vififo_vaddr) { 307 dev_err(sess->core->dev, "Failed to request VIFIFO buffer\n"); 308 ret = -ENOMEM; 309 goto bufs_done; 310 } 311 312 sess->should_stop = 0; 313 sess->keyframe_found = 0; 314 sess->last_offset = 0; 315 sess->wrap_count = 0; 316 sess->pixelaspect.numerator = 1; 317 sess->pixelaspect.denominator = 1; 318 atomic_set(&sess->esparser_queued_bufs, 0); 319 v4l2_ctrl_s_ctrl(sess->ctrl_min_buf_capture, 1); 320 321 ret = vdec_poweron(sess); 322 if (ret) 323 goto vififo_free; 324 325 sess->sequence_cap = 0; 326 if (vdec_codec_needs_recycle(sess)) 327 sess->recycle_thread = kthread_run(vdec_recycle_thread, sess, 328 "vdec_recycle"); 329 330 sess->status = STATUS_RUNNING; 331 core->cur_sess = sess; 332 333 return 0; 334 335 vififo_free: 336 dma_free_coherent(sess->core->dev, sess->vififo_size, 337 sess->vififo_vaddr, sess->vififo_paddr); 338 bufs_done: 339 while ((buf = v4l2_m2m_src_buf_remove(sess->m2m_ctx))) 340 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); 341 while ((buf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx))) 342 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED); 343 344 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 345 sess->streamon_out = 0; 346 else 347 sess->streamon_cap = 0; 348 349 return ret; 350 } 351 352 static void vdec_free_canvas(struct amvdec_session *sess) 353 { 354 int i; 355 356 for (i = 0; i < sess->canvas_num; ++i) 357 meson_canvas_free(sess->core->canvas, sess->canvas_alloc[i]); 358 359 sess->canvas_num = 0; 360 } 361 362 static void vdec_reset_timestamps(struct amvdec_session *sess) 363 { 364 struct amvdec_timestamp *tmp, *n; 365 366 list_for_each_entry_safe(tmp, n, &sess->timestamps, list) { 367 list_del(&tmp->list); 368 kfree(tmp); 369 } 370 } 371 372 static void vdec_reset_bufs_recycle(struct amvdec_session *sess) 373 { 374 struct amvdec_buffer *tmp, *n; 375 376 list_for_each_entry_safe(tmp, n, &sess->bufs_recycle, list) { 377 list_del(&tmp->list); 378 kfree(tmp); 379 } 380 } 381 382 static void vdec_stop_streaming(struct vb2_queue *q) 383 { 384 struct amvdec_session *sess = vb2_get_drv_priv(q); 385 struct amvdec_core *core = sess->core; 386 struct vb2_v4l2_buffer *buf; 387 388 if (sess->status == STATUS_RUNNING || 389 (sess->status == STATUS_NEEDS_RESUME && 390 (!sess->streamon_out || !sess->streamon_cap))) { 391 if (vdec_codec_needs_recycle(sess)) 392 kthread_stop(sess->recycle_thread); 393 394 vdec_poweroff(sess); 395 vdec_free_canvas(sess); 396 dma_free_coherent(sess->core->dev, sess->vififo_size, 397 sess->vififo_vaddr, sess->vififo_paddr); 398 vdec_reset_timestamps(sess); 399 vdec_reset_bufs_recycle(sess); 400 kfree(sess->priv); 401 sess->priv = NULL; 402 core->cur_sess = NULL; 403 sess->status = STATUS_STOPPED; 404 } 405 406 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 407 while ((buf = v4l2_m2m_src_buf_remove(sess->m2m_ctx))) 408 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); 409 410 sess->streamon_out = 0; 411 } else { 412 while ((buf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx))) 413 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); 414 415 sess->streamon_cap = 0; 416 } 417 } 418 419 static int vdec_vb2_buf_prepare(struct vb2_buffer *vb) 420 { 421 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 422 423 vbuf->field = V4L2_FIELD_NONE; 424 return 0; 425 } 426 427 static const struct vb2_ops vdec_vb2_ops = { 428 .queue_setup = vdec_queue_setup, 429 .start_streaming = vdec_start_streaming, 430 .stop_streaming = vdec_stop_streaming, 431 .buf_queue = vdec_vb2_buf_queue, 432 .buf_prepare = vdec_vb2_buf_prepare, 433 .wait_prepare = vb2_ops_wait_prepare, 434 .wait_finish = vb2_ops_wait_finish, 435 }; 436 437 static int 438 vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 439 { 440 strscpy(cap->driver, "meson-vdec", sizeof(cap->driver)); 441 strscpy(cap->card, "Amlogic Video Decoder", sizeof(cap->card)); 442 strscpy(cap->bus_info, "platform:meson-vdec", sizeof(cap->bus_info)); 443 444 return 0; 445 } 446 447 static const struct amvdec_format * 448 find_format(const struct amvdec_format *fmts, u32 size, u32 pixfmt) 449 { 450 unsigned int i; 451 452 for (i = 0; i < size; i++) { 453 if (fmts[i].pixfmt == pixfmt) 454 return &fmts[i]; 455 } 456 457 return NULL; 458 } 459 460 static unsigned int 461 vdec_supports_pixfmt_cap(const struct amvdec_format *fmt_out, u32 pixfmt_cap) 462 { 463 int i; 464 465 for (i = 0; fmt_out->pixfmts_cap[i]; i++) 466 if (fmt_out->pixfmts_cap[i] == pixfmt_cap) 467 return 1; 468 469 return 0; 470 } 471 472 static const struct amvdec_format * 473 vdec_try_fmt_common(struct amvdec_session *sess, u32 size, 474 struct v4l2_format *f) 475 { 476 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 477 struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; 478 const struct amvdec_format *fmts = sess->core->platform->formats; 479 const struct amvdec_format *fmt_out; 480 481 memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); 482 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 483 484 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 485 fmt_out = find_format(fmts, size, pixmp->pixelformat); 486 if (!fmt_out) { 487 pixmp->pixelformat = V4L2_PIX_FMT_MPEG2; 488 fmt_out = find_format(fmts, size, pixmp->pixelformat); 489 } 490 491 pfmt[0].sizeimage = 492 get_output_size(pixmp->width, pixmp->height); 493 pfmt[0].bytesperline = 0; 494 pixmp->num_planes = 1; 495 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 496 fmt_out = sess->fmt_out; 497 if (!vdec_supports_pixfmt_cap(fmt_out, pixmp->pixelformat)) 498 pixmp->pixelformat = fmt_out->pixfmts_cap[0]; 499 500 memset(pfmt[1].reserved, 0, sizeof(pfmt[1].reserved)); 501 if (pixmp->pixelformat == V4L2_PIX_FMT_NV12M) { 502 pfmt[0].sizeimage = 503 get_output_size(pixmp->width, pixmp->height); 504 pfmt[0].bytesperline = ALIGN(pixmp->width, 64); 505 506 pfmt[1].sizeimage = 507 get_output_size(pixmp->width, pixmp->height) / 2; 508 pfmt[1].bytesperline = ALIGN(pixmp->width, 64); 509 pixmp->num_planes = 2; 510 } else if (pixmp->pixelformat == V4L2_PIX_FMT_YUV420M) { 511 pfmt[0].sizeimage = 512 get_output_size(pixmp->width, pixmp->height); 513 pfmt[0].bytesperline = ALIGN(pixmp->width, 64); 514 515 pfmt[1].sizeimage = 516 get_output_size(pixmp->width, pixmp->height) / 4; 517 pfmt[1].bytesperline = ALIGN(pixmp->width, 64) / 2; 518 519 pfmt[2].sizeimage = 520 get_output_size(pixmp->width, pixmp->height) / 4; 521 pfmt[2].bytesperline = ALIGN(pixmp->width, 64) / 2; 522 pixmp->num_planes = 3; 523 } 524 } else { 525 return NULL; 526 } 527 528 pixmp->width = clamp(pixmp->width, (u32)256, fmt_out->max_width); 529 pixmp->height = clamp(pixmp->height, (u32)144, fmt_out->max_height); 530 531 if (pixmp->field == V4L2_FIELD_ANY) 532 pixmp->field = V4L2_FIELD_NONE; 533 534 return fmt_out; 535 } 536 537 static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f) 538 { 539 struct amvdec_session *sess = 540 container_of(file->private_data, struct amvdec_session, fh); 541 542 vdec_try_fmt_common(sess, sess->core->platform->num_formats, f); 543 544 return 0; 545 } 546 547 static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f) 548 { 549 struct amvdec_session *sess = 550 container_of(file->private_data, struct amvdec_session, fh); 551 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 552 553 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 554 pixmp->pixelformat = sess->pixfmt_cap; 555 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 556 pixmp->pixelformat = sess->fmt_out->pixfmt; 557 558 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 559 pixmp->width = sess->width; 560 pixmp->height = sess->height; 561 pixmp->colorspace = sess->colorspace; 562 pixmp->ycbcr_enc = sess->ycbcr_enc; 563 pixmp->quantization = sess->quantization; 564 pixmp->xfer_func = sess->xfer_func; 565 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 566 pixmp->width = sess->width; 567 pixmp->height = sess->height; 568 } 569 570 vdec_try_fmt_common(sess, sess->core->platform->num_formats, f); 571 572 return 0; 573 } 574 575 static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f) 576 { 577 struct amvdec_session *sess = 578 container_of(file->private_data, struct amvdec_session, fh); 579 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 580 u32 num_formats = sess->core->platform->num_formats; 581 const struct amvdec_format *fmt_out; 582 struct v4l2_pix_format_mplane orig_pixmp; 583 struct v4l2_format format; 584 u32 pixfmt_out = 0, pixfmt_cap = 0; 585 586 orig_pixmp = *pixmp; 587 588 fmt_out = vdec_try_fmt_common(sess, num_formats, f); 589 590 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 591 pixfmt_out = pixmp->pixelformat; 592 pixfmt_cap = sess->pixfmt_cap; 593 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 594 pixfmt_cap = pixmp->pixelformat; 595 pixfmt_out = sess->fmt_out->pixfmt; 596 } 597 598 memset(&format, 0, sizeof(format)); 599 600 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 601 format.fmt.pix_mp.pixelformat = pixfmt_out; 602 format.fmt.pix_mp.width = orig_pixmp.width; 603 format.fmt.pix_mp.height = orig_pixmp.height; 604 vdec_try_fmt_common(sess, num_formats, &format); 605 606 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 607 sess->width = format.fmt.pix_mp.width; 608 sess->height = format.fmt.pix_mp.height; 609 sess->colorspace = pixmp->colorspace; 610 sess->ycbcr_enc = pixmp->ycbcr_enc; 611 sess->quantization = pixmp->quantization; 612 sess->xfer_func = pixmp->xfer_func; 613 } 614 615 memset(&format, 0, sizeof(format)); 616 617 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 618 format.fmt.pix_mp.pixelformat = pixfmt_cap; 619 format.fmt.pix_mp.width = orig_pixmp.width; 620 format.fmt.pix_mp.height = orig_pixmp.height; 621 vdec_try_fmt_common(sess, num_formats, &format); 622 623 sess->width = format.fmt.pix_mp.width; 624 sess->height = format.fmt.pix_mp.height; 625 626 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 627 sess->fmt_out = fmt_out; 628 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 629 sess->pixfmt_cap = format.fmt.pix_mp.pixelformat; 630 631 return 0; 632 } 633 634 static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) 635 { 636 struct amvdec_session *sess = 637 container_of(file->private_data, struct amvdec_session, fh); 638 const struct vdec_platform *platform = sess->core->platform; 639 const struct amvdec_format *fmt_out; 640 641 memset(f->reserved, 0, sizeof(f->reserved)); 642 643 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 644 if (f->index >= platform->num_formats) 645 return -EINVAL; 646 647 fmt_out = &platform->formats[f->index]; 648 f->pixelformat = fmt_out->pixfmt; 649 f->flags = fmt_out->flags; 650 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 651 fmt_out = sess->fmt_out; 652 if (f->index >= 4 || !fmt_out->pixfmts_cap[f->index]) 653 return -EINVAL; 654 655 f->pixelformat = fmt_out->pixfmts_cap[f->index]; 656 } else { 657 return -EINVAL; 658 } 659 660 return 0; 661 } 662 663 static int vdec_enum_framesizes(struct file *file, void *fh, 664 struct v4l2_frmsizeenum *fsize) 665 { 666 struct amvdec_session *sess = 667 container_of(file->private_data, struct amvdec_session, fh); 668 const struct amvdec_format *formats = sess->core->platform->formats; 669 const struct amvdec_format *fmt; 670 u32 num_formats = sess->core->platform->num_formats; 671 672 fmt = find_format(formats, num_formats, fsize->pixel_format); 673 if (!fmt || fsize->index) 674 return -EINVAL; 675 676 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; 677 678 fsize->stepwise.min_width = 256; 679 fsize->stepwise.max_width = fmt->max_width; 680 fsize->stepwise.step_width = 1; 681 fsize->stepwise.min_height = 144; 682 fsize->stepwise.max_height = fmt->max_height; 683 fsize->stepwise.step_height = 1; 684 685 return 0; 686 } 687 688 static int 689 vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) 690 { 691 struct amvdec_session *sess = 692 container_of(file->private_data, struct amvdec_session, fh); 693 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; 694 struct device *dev = sess->core->dev; 695 int ret; 696 697 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); 698 if (ret) 699 return ret; 700 701 if (!(sess->streamon_out & sess->streamon_cap)) 702 return 0; 703 704 /* Currently not handled since we do not support dynamic resolution 705 * for MPEG2. We consider both queues streaming to mean that the 706 * decoding session is started 707 */ 708 if (cmd->cmd == V4L2_DEC_CMD_START) 709 return 0; 710 711 /* Should not happen */ 712 if (cmd->cmd != V4L2_DEC_CMD_STOP) 713 return -EINVAL; 714 715 dev_dbg(dev, "Received V4L2_DEC_CMD_STOP\n"); 716 sess->should_stop = 1; 717 718 vdec_wait_inactive(sess); 719 720 if (codec_ops->drain) { 721 codec_ops->drain(sess); 722 } else if (codec_ops->eos_sequence) { 723 u32 len; 724 const u8 *data = codec_ops->eos_sequence(&len); 725 726 esparser_queue_eos(sess->core, data, len); 727 } 728 729 return ret; 730 } 731 732 static int vdec_subscribe_event(struct v4l2_fh *fh, 733 const struct v4l2_event_subscription *sub) 734 { 735 switch (sub->type) { 736 case V4L2_EVENT_EOS: 737 case V4L2_EVENT_SOURCE_CHANGE: 738 return v4l2_event_subscribe(fh, sub, 0, NULL); 739 case V4L2_EVENT_CTRL: 740 return v4l2_ctrl_subscribe_event(fh, sub); 741 default: 742 return -EINVAL; 743 } 744 } 745 746 static int vdec_g_pixelaspect(struct file *file, void *fh, int type, 747 struct v4l2_fract *f) 748 { 749 struct amvdec_session *sess = 750 container_of(file->private_data, struct amvdec_session, fh); 751 752 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 753 return -EINVAL; 754 755 *f = sess->pixelaspect; 756 return 0; 757 } 758 759 static const struct v4l2_ioctl_ops vdec_ioctl_ops = { 760 .vidioc_querycap = vdec_querycap, 761 .vidioc_enum_fmt_vid_cap = vdec_enum_fmt, 762 .vidioc_enum_fmt_vid_out = vdec_enum_fmt, 763 .vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt, 764 .vidioc_s_fmt_vid_out_mplane = vdec_s_fmt, 765 .vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt, 766 .vidioc_g_fmt_vid_out_mplane = vdec_g_fmt, 767 .vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt, 768 .vidioc_try_fmt_vid_out_mplane = vdec_try_fmt, 769 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 770 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 771 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 772 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 773 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 774 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 775 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 776 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 777 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 778 .vidioc_enum_framesizes = vdec_enum_framesizes, 779 .vidioc_subscribe_event = vdec_subscribe_event, 780 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 781 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd, 782 .vidioc_decoder_cmd = vdec_decoder_cmd, 783 .vidioc_g_pixelaspect = vdec_g_pixelaspect, 784 }; 785 786 static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, 787 struct vb2_queue *dst_vq) 788 { 789 struct amvdec_session *sess = priv; 790 int ret; 791 792 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 793 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 794 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 795 src_vq->ops = &vdec_vb2_ops; 796 src_vq->mem_ops = &vb2_dma_contig_memops; 797 src_vq->drv_priv = sess; 798 src_vq->buf_struct_size = sizeof(struct dummy_buf); 799 src_vq->min_buffers_needed = 1; 800 src_vq->dev = sess->core->dev; 801 src_vq->lock = &sess->lock; 802 ret = vb2_queue_init(src_vq); 803 if (ret) 804 return ret; 805 806 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 807 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 808 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 809 dst_vq->ops = &vdec_vb2_ops; 810 dst_vq->mem_ops = &vb2_dma_contig_memops; 811 dst_vq->drv_priv = sess; 812 dst_vq->buf_struct_size = sizeof(struct dummy_buf); 813 dst_vq->min_buffers_needed = 1; 814 dst_vq->dev = sess->core->dev; 815 dst_vq->lock = &sess->lock; 816 ret = vb2_queue_init(dst_vq); 817 if (ret) { 818 vb2_queue_release(src_vq); 819 return ret; 820 } 821 822 return 0; 823 } 824 825 static int vdec_init_ctrls(struct amvdec_session *sess) 826 { 827 struct v4l2_ctrl_handler *ctrl_handler = &sess->ctrl_handler; 828 int ret; 829 830 ret = v4l2_ctrl_handler_init(ctrl_handler, 1); 831 if (ret) 832 return ret; 833 834 sess->ctrl_min_buf_capture = 835 v4l2_ctrl_new_std(ctrl_handler, NULL, 836 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 837 1); 838 839 ret = ctrl_handler->error; 840 if (ret) { 841 v4l2_ctrl_handler_free(ctrl_handler); 842 return ret; 843 } 844 845 return 0; 846 } 847 848 static int vdec_open(struct file *file) 849 { 850 struct amvdec_core *core = video_drvdata(file); 851 struct device *dev = core->dev; 852 const struct amvdec_format *formats = core->platform->formats; 853 struct amvdec_session *sess; 854 int ret; 855 856 sess = kzalloc(sizeof(*sess), GFP_KERNEL); 857 if (!sess) 858 return -ENOMEM; 859 860 sess->core = core; 861 862 sess->m2m_dev = v4l2_m2m_init(&vdec_m2m_ops); 863 if (IS_ERR(sess->m2m_dev)) { 864 dev_err(dev, "Fail to v4l2_m2m_init\n"); 865 ret = PTR_ERR(sess->m2m_dev); 866 goto err_free_sess; 867 } 868 869 sess->m2m_ctx = v4l2_m2m_ctx_init(sess->m2m_dev, sess, m2m_queue_init); 870 if (IS_ERR(sess->m2m_ctx)) { 871 dev_err(dev, "Fail to v4l2_m2m_ctx_init\n"); 872 ret = PTR_ERR(sess->m2m_ctx); 873 goto err_m2m_release; 874 } 875 876 ret = vdec_init_ctrls(sess); 877 if (ret) 878 goto err_m2m_release; 879 880 sess->pixfmt_cap = formats[0].pixfmts_cap[0]; 881 sess->fmt_out = &formats[0]; 882 sess->width = 1280; 883 sess->height = 720; 884 sess->pixelaspect.numerator = 1; 885 sess->pixelaspect.denominator = 1; 886 887 INIT_LIST_HEAD(&sess->timestamps); 888 INIT_LIST_HEAD(&sess->bufs_recycle); 889 INIT_WORK(&sess->esparser_queue_work, esparser_queue_all_src); 890 mutex_init(&sess->lock); 891 mutex_init(&sess->bufs_recycle_lock); 892 spin_lock_init(&sess->ts_spinlock); 893 894 v4l2_fh_init(&sess->fh, core->vdev_dec); 895 sess->fh.ctrl_handler = &sess->ctrl_handler; 896 v4l2_fh_add(&sess->fh); 897 sess->fh.m2m_ctx = sess->m2m_ctx; 898 file->private_data = &sess->fh; 899 900 return 0; 901 902 err_m2m_release: 903 v4l2_m2m_release(sess->m2m_dev); 904 err_free_sess: 905 kfree(sess); 906 return ret; 907 } 908 909 static int vdec_close(struct file *file) 910 { 911 struct amvdec_session *sess = 912 container_of(file->private_data, struct amvdec_session, fh); 913 914 v4l2_m2m_ctx_release(sess->m2m_ctx); 915 v4l2_m2m_release(sess->m2m_dev); 916 v4l2_fh_del(&sess->fh); 917 v4l2_fh_exit(&sess->fh); 918 919 mutex_destroy(&sess->lock); 920 mutex_destroy(&sess->bufs_recycle_lock); 921 922 kfree(sess); 923 924 return 0; 925 } 926 927 static const struct v4l2_file_operations vdec_fops = { 928 .owner = THIS_MODULE, 929 .open = vdec_open, 930 .release = vdec_close, 931 .unlocked_ioctl = video_ioctl2, 932 .poll = v4l2_m2m_fop_poll, 933 .mmap = v4l2_m2m_fop_mmap, 934 }; 935 936 static irqreturn_t vdec_isr(int irq, void *data) 937 { 938 struct amvdec_core *core = data; 939 struct amvdec_session *sess = core->cur_sess; 940 941 sess->last_irq_jiffies = get_jiffies_64(); 942 943 return sess->fmt_out->codec_ops->isr(sess); 944 } 945 946 static irqreturn_t vdec_threaded_isr(int irq, void *data) 947 { 948 struct amvdec_core *core = data; 949 struct amvdec_session *sess = core->cur_sess; 950 951 return sess->fmt_out->codec_ops->threaded_isr(sess); 952 } 953 954 static const struct of_device_id vdec_dt_match[] = { 955 { .compatible = "amlogic,gxbb-vdec", 956 .data = &vdec_platform_gxbb }, 957 { .compatible = "amlogic,gxm-vdec", 958 .data = &vdec_platform_gxm }, 959 { .compatible = "amlogic,gxl-vdec", 960 .data = &vdec_platform_gxl }, 961 { .compatible = "amlogic,g12a-vdec", 962 .data = &vdec_platform_g12a }, 963 { .compatible = "amlogic,sm1-vdec", 964 .data = &vdec_platform_sm1 }, 965 {} 966 }; 967 MODULE_DEVICE_TABLE(of, vdec_dt_match); 968 969 static int vdec_probe(struct platform_device *pdev) 970 { 971 struct device *dev = &pdev->dev; 972 struct video_device *vdev; 973 struct amvdec_core *core; 974 struct resource *r; 975 const struct of_device_id *of_id; 976 int irq; 977 int ret; 978 979 core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL); 980 if (!core) 981 return -ENOMEM; 982 983 core->dev = dev; 984 platform_set_drvdata(pdev, core); 985 986 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dos"); 987 core->dos_base = devm_ioremap_resource(dev, r); 988 if (IS_ERR(core->dos_base)) { 989 dev_err(dev, "Couldn't remap DOS memory\n"); 990 return PTR_ERR(core->dos_base); 991 } 992 993 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "esparser"); 994 core->esparser_base = devm_ioremap_resource(dev, r); 995 if (IS_ERR(core->esparser_base)) { 996 dev_err(dev, "Couldn't remap ESPARSER memory\n"); 997 return PTR_ERR(core->esparser_base); 998 } 999 1000 core->regmap_ao = 1001 syscon_regmap_lookup_by_phandle(dev->of_node, 1002 "amlogic,ao-sysctrl"); 1003 if (IS_ERR(core->regmap_ao)) { 1004 dev_err(dev, "Couldn't regmap AO sysctrl\n"); 1005 return PTR_ERR(core->regmap_ao); 1006 } 1007 1008 core->canvas = meson_canvas_get(dev); 1009 if (IS_ERR(core->canvas)) 1010 return PTR_ERR(core->canvas); 1011 1012 of_id = of_match_node(vdec_dt_match, dev->of_node); 1013 core->platform = of_id->data; 1014 1015 if (core->platform->revision == VDEC_REVISION_G12A || 1016 core->platform->revision == VDEC_REVISION_SM1) { 1017 core->vdec_hevcf_clk = devm_clk_get(dev, "vdec_hevcf"); 1018 if (IS_ERR(core->vdec_hevcf_clk)) 1019 return -EPROBE_DEFER; 1020 } 1021 1022 core->dos_parser_clk = devm_clk_get(dev, "dos_parser"); 1023 if (IS_ERR(core->dos_parser_clk)) 1024 return -EPROBE_DEFER; 1025 1026 core->dos_clk = devm_clk_get(dev, "dos"); 1027 if (IS_ERR(core->dos_clk)) 1028 return -EPROBE_DEFER; 1029 1030 core->vdec_1_clk = devm_clk_get(dev, "vdec_1"); 1031 if (IS_ERR(core->vdec_1_clk)) 1032 return -EPROBE_DEFER; 1033 1034 core->vdec_hevc_clk = devm_clk_get(dev, "vdec_hevc"); 1035 if (IS_ERR(core->vdec_hevc_clk)) 1036 return -EPROBE_DEFER; 1037 1038 irq = platform_get_irq_byname(pdev, "vdec"); 1039 if (irq < 0) 1040 return irq; 1041 1042 ret = devm_request_threaded_irq(core->dev, irq, vdec_isr, 1043 vdec_threaded_isr, IRQF_ONESHOT, 1044 "vdec", core); 1045 if (ret) 1046 return ret; 1047 1048 ret = esparser_init(pdev, core); 1049 if (ret) 1050 return ret; 1051 1052 ret = v4l2_device_register(dev, &core->v4l2_dev); 1053 if (ret) { 1054 dev_err(dev, "Couldn't register v4l2 device\n"); 1055 return -ENOMEM; 1056 } 1057 1058 vdev = video_device_alloc(); 1059 if (!vdev) { 1060 ret = -ENOMEM; 1061 goto err_vdev_release; 1062 } 1063 1064 core->vdev_dec = vdev; 1065 core->dev_dec = dev; 1066 mutex_init(&core->lock); 1067 1068 strscpy(vdev->name, "meson-video-decoder", sizeof(vdev->name)); 1069 vdev->release = video_device_release; 1070 vdev->fops = &vdec_fops; 1071 vdev->ioctl_ops = &vdec_ioctl_ops; 1072 vdev->vfl_dir = VFL_DIR_M2M; 1073 vdev->v4l2_dev = &core->v4l2_dev; 1074 vdev->lock = &core->lock; 1075 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 1076 1077 video_set_drvdata(vdev, core); 1078 1079 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 1080 if (ret) { 1081 dev_err(dev, "Failed registering video device\n"); 1082 goto err_vdev_release; 1083 } 1084 1085 return 0; 1086 1087 err_vdev_release: 1088 video_device_release(vdev); 1089 return ret; 1090 } 1091 1092 static int vdec_remove(struct platform_device *pdev) 1093 { 1094 struct amvdec_core *core = platform_get_drvdata(pdev); 1095 1096 video_unregister_device(core->vdev_dec); 1097 1098 return 0; 1099 } 1100 1101 static struct platform_driver meson_vdec_driver = { 1102 .probe = vdec_probe, 1103 .remove = vdec_remove, 1104 .driver = { 1105 .name = "meson-vdec", 1106 .of_match_table = vdec_dt_match, 1107 }, 1108 }; 1109 module_platform_driver(meson_vdec_driver); 1110 1111 MODULE_DESCRIPTION("Meson video decoder driver for GXBB/GXL/GXM"); 1112 MODULE_AUTHOR("Maxime Jourdan <mjourdan@baylibre.com>"); 1113 MODULE_LICENSE("GPL"); 1114