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