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