21d2591e7b7b40f10dad46f50ea360c7d9461e57
[platform/kernel/linux-rpi.git] / drivers / staging / media / rockchip / vpu / rockchip_vpu_drv.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Rockchip VPU codec driver
4  *
5  * Copyright (C) 2018 Collabora, Ltd.
6  * Copyright 2018 Google LLC.
7  *      Tomasz Figa <tfiga@chromium.org>
8  *
9  * Based on s5p-mfc driver by Samsung Electronics Co., Ltd.
10  * Copyright (C) 2011 Samsung Electronics Co., Ltd.
11  */
12
13 #include <linux/clk.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/slab.h>
20 #include <linux/videodev2.h>
21 #include <linux/workqueue.h>
22 #include <media/v4l2-event.h>
23 #include <media/v4l2-mem2mem.h>
24 #include <media/videobuf2-core.h>
25 #include <media/videobuf2-vmalloc.h>
26
27 #include "rockchip_vpu_common.h"
28 #include "rockchip_vpu.h"
29 #include "rockchip_vpu_hw.h"
30
31 #define DRIVER_NAME "rockchip-vpu"
32
33 int rockchip_vpu_debug;
34 module_param_named(debug, rockchip_vpu_debug, int, 0644);
35 MODULE_PARM_DESC(debug,
36                  "Debug level - higher value produces more verbose messages");
37
38 static void rockchip_vpu_job_finish(struct rockchip_vpu_dev *vpu,
39                                     struct rockchip_vpu_ctx *ctx,
40                                     unsigned int bytesused,
41                                     enum vb2_buffer_state result)
42 {
43         struct vb2_v4l2_buffer *src, *dst;
44         size_t avail_size;
45
46         pm_runtime_mark_last_busy(vpu->dev);
47         pm_runtime_put_autosuspend(vpu->dev);
48         clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks);
49
50         src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
51         dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
52
53         if (WARN_ON(!src))
54                 return;
55         if (WARN_ON(!dst))
56                 return;
57
58         src->sequence = ctx->sequence_out++;
59         dst->sequence = ctx->sequence_cap++;
60
61         v4l2_m2m_buf_copy_metadata(src, dst, true);
62
63         avail_size = vb2_plane_size(&dst->vb2_buf, 0) -
64                      ctx->vpu_dst_fmt->header_size;
65         if (bytesused <= avail_size) {
66                 /*
67                  * The bounce buffer is only for the JPEG encoder.
68                  * TODO: Rework the JPEG encoder to eliminate the need
69                  * for a bounce buffer.
70                  */
71                 if (ctx->jpeg_enc.bounce_buffer.cpu) {
72                         memcpy(vb2_plane_vaddr(&dst->vb2_buf, 0) +
73                                ctx->vpu_dst_fmt->header_size,
74                                ctx->jpeg_enc.bounce_buffer.cpu, bytesused);
75                 }
76                 dst->vb2_buf.planes[0].bytesused =
77                         ctx->vpu_dst_fmt->header_size + bytesused;
78         } else {
79                 result = VB2_BUF_STATE_ERROR;
80         }
81
82         v4l2_m2m_buf_done(src, result);
83         v4l2_m2m_buf_done(dst, result);
84
85         v4l2_m2m_job_finish(vpu->m2m_dev, ctx->fh.m2m_ctx);
86 }
87
88 void rockchip_vpu_irq_done(struct rockchip_vpu_dev *vpu,
89                            unsigned int bytesused,
90                            enum vb2_buffer_state result)
91 {
92         struct rockchip_vpu_ctx *ctx =
93                 v4l2_m2m_get_curr_priv(vpu->m2m_dev);
94
95         /*
96          * If cancel_delayed_work returns false
97          * the timeout expired. The watchdog is running,
98          * and will take care of finishing the job.
99          */
100         if (cancel_delayed_work(&vpu->watchdog_work))
101                 rockchip_vpu_job_finish(vpu, ctx, bytesused, result);
102 }
103
104 void rockchip_vpu_watchdog(struct work_struct *work)
105 {
106         struct rockchip_vpu_dev *vpu;
107         struct rockchip_vpu_ctx *ctx;
108
109         vpu = container_of(to_delayed_work(work),
110                            struct rockchip_vpu_dev, watchdog_work);
111         ctx = v4l2_m2m_get_curr_priv(vpu->m2m_dev);
112         if (ctx) {
113                 vpu_err("frame processing timed out!\n");
114                 ctx->codec_ops->reset(ctx);
115                 rockchip_vpu_job_finish(vpu, ctx, 0, VB2_BUF_STATE_ERROR);
116         }
117 }
118
119 static void device_run(void *priv)
120 {
121         struct rockchip_vpu_ctx *ctx = priv;
122         int ret;
123
124         ret = clk_bulk_enable(ctx->dev->variant->num_clocks, ctx->dev->clocks);
125         if (ret)
126                 goto err_cancel_job;
127         ret = pm_runtime_get_sync(ctx->dev->dev);
128         if (ret < 0)
129                 goto err_cancel_job;
130
131         ctx->codec_ops->run(ctx);
132         return;
133
134 err_cancel_job:
135         rockchip_vpu_job_finish(ctx->dev, ctx, 0, VB2_BUF_STATE_ERROR);
136 }
137
138 static struct v4l2_m2m_ops vpu_m2m_ops = {
139         .device_run = device_run,
140 };
141
142 static int
143 enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
144 {
145         struct rockchip_vpu_ctx *ctx = priv;
146         int ret;
147
148         src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
149         src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
150         src_vq->drv_priv = ctx;
151         src_vq->ops = &rockchip_vpu_enc_queue_ops;
152         src_vq->mem_ops = &vb2_dma_contig_memops;
153
154         /*
155          * Driver does mostly sequential access, so sacrifice TLB efficiency
156          * for faster allocation. Also, no CPU access on the source queue,
157          * so no kernel mapping needed.
158          */
159         src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES |
160                             DMA_ATTR_NO_KERNEL_MAPPING;
161         src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
162         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
163         src_vq->lock = &ctx->dev->vpu_mutex;
164         src_vq->dev = ctx->dev->v4l2_dev.dev;
165
166         ret = vb2_queue_init(src_vq);
167         if (ret)
168                 return ret;
169
170         /*
171          * The CAPTURE queue doesn't need dma memory,
172          * as the CPU needs to create the JPEG frames,
173          * from the hardware-produced JPEG payload.
174          *
175          * For the DMA destination buffer, we use
176          * a bounce buffer.
177          */
178         dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
179         dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
180         dst_vq->drv_priv = ctx;
181         dst_vq->ops = &rockchip_vpu_enc_queue_ops;
182         dst_vq->mem_ops = &vb2_vmalloc_memops;
183         dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
184         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
185         dst_vq->lock = &ctx->dev->vpu_mutex;
186         dst_vq->dev = ctx->dev->v4l2_dev.dev;
187
188         return vb2_queue_init(dst_vq);
189 }
190
191 static int rockchip_vpu_s_ctrl(struct v4l2_ctrl *ctrl)
192 {
193         struct rockchip_vpu_ctx *ctx;
194
195         ctx = container_of(ctrl->handler,
196                            struct rockchip_vpu_ctx, ctrl_handler);
197
198         vpu_debug(1, "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val);
199
200         switch (ctrl->id) {
201         case V4L2_CID_JPEG_COMPRESSION_QUALITY:
202                 ctx->jpeg_quality = ctrl->val;
203                 break;
204         default:
205                 return -EINVAL;
206         }
207
208         return 0;
209 }
210
211 static const struct v4l2_ctrl_ops rockchip_vpu_ctrl_ops = {
212         .s_ctrl = rockchip_vpu_s_ctrl,
213 };
214
215 static int rockchip_vpu_ctrls_setup(struct rockchip_vpu_dev *vpu,
216                                     struct rockchip_vpu_ctx *ctx)
217 {
218         v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
219         if (vpu->variant->codec & RK_VPU_CODEC_JPEG) {
220                 v4l2_ctrl_new_std(&ctx->ctrl_handler, &rockchip_vpu_ctrl_ops,
221                                   V4L2_CID_JPEG_COMPRESSION_QUALITY,
222                                   5, 100, 1, 50);
223                 if (ctx->ctrl_handler.error) {
224                         vpu_err("Adding JPEG control failed %d\n",
225                                 ctx->ctrl_handler.error);
226                         v4l2_ctrl_handler_free(&ctx->ctrl_handler);
227                         return ctx->ctrl_handler.error;
228                 }
229         }
230
231         return v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
232 }
233
234 /*
235  * V4L2 file operations.
236  */
237
238 static int rockchip_vpu_open(struct file *filp)
239 {
240         struct rockchip_vpu_dev *vpu = video_drvdata(filp);
241         struct video_device *vdev = video_devdata(filp);
242         struct rockchip_vpu_ctx *ctx;
243         int ret;
244
245         /*
246          * We do not need any extra locking here, because we operate only
247          * on local data here, except reading few fields from dev, which
248          * do not change through device's lifetime (which is guaranteed by
249          * reference on module from open()) and V4L2 internal objects (such
250          * as vdev and ctx->fh), which have proper locking done in respective
251          * helper functions used here.
252          */
253
254         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
255         if (!ctx)
256                 return -ENOMEM;
257
258         ctx->dev = vpu;
259         if (vdev == vpu->vfd_enc)
260                 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
261                                                     &enc_queue_init);
262         else
263                 ctx->fh.m2m_ctx = ERR_PTR(-ENODEV);
264         if (IS_ERR(ctx->fh.m2m_ctx)) {
265                 ret = PTR_ERR(ctx->fh.m2m_ctx);
266                 kfree(ctx);
267                 return ret;
268         }
269
270         v4l2_fh_init(&ctx->fh, vdev);
271         filp->private_data = &ctx->fh;
272         v4l2_fh_add(&ctx->fh);
273
274         if (vdev == vpu->vfd_enc) {
275                 rockchip_vpu_enc_reset_dst_fmt(vpu, ctx);
276                 rockchip_vpu_enc_reset_src_fmt(vpu, ctx);
277         }
278
279         ret = rockchip_vpu_ctrls_setup(vpu, ctx);
280         if (ret) {
281                 vpu_err("Failed to set up controls\n");
282                 goto err_fh_free;
283         }
284         ctx->fh.ctrl_handler = &ctx->ctrl_handler;
285
286         return 0;
287
288 err_fh_free:
289         v4l2_fh_del(&ctx->fh);
290         v4l2_fh_exit(&ctx->fh);
291         kfree(ctx);
292         return ret;
293 }
294
295 static int rockchip_vpu_release(struct file *filp)
296 {
297         struct rockchip_vpu_ctx *ctx =
298                 container_of(filp->private_data, struct rockchip_vpu_ctx, fh);
299
300         /*
301          * No need for extra locking because this was the last reference
302          * to this file.
303          */
304         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
305         v4l2_fh_del(&ctx->fh);
306         v4l2_fh_exit(&ctx->fh);
307         v4l2_ctrl_handler_free(&ctx->ctrl_handler);
308         kfree(ctx);
309
310         return 0;
311 }
312
313 static const struct v4l2_file_operations rockchip_vpu_fops = {
314         .owner = THIS_MODULE,
315         .open = rockchip_vpu_open,
316         .release = rockchip_vpu_release,
317         .poll = v4l2_m2m_fop_poll,
318         .unlocked_ioctl = video_ioctl2,
319         .mmap = v4l2_m2m_fop_mmap,
320 };
321
322 static const struct of_device_id of_rockchip_vpu_match[] = {
323         { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
324         { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, },
325         { /* sentinel */ }
326 };
327 MODULE_DEVICE_TABLE(of, of_rockchip_vpu_match);
328
329 static int rockchip_vpu_video_device_register(struct rockchip_vpu_dev *vpu)
330 {
331         const struct of_device_id *match;
332         struct video_device *vfd;
333         int function, ret;
334
335         match = of_match_node(of_rockchip_vpu_match, vpu->dev->of_node);
336         vfd = video_device_alloc();
337         if (!vfd) {
338                 v4l2_err(&vpu->v4l2_dev, "Failed to allocate video device\n");
339                 return -ENOMEM;
340         }
341
342         vfd->fops = &rockchip_vpu_fops;
343         vfd->release = video_device_release;
344         vfd->lock = &vpu->vpu_mutex;
345         vfd->v4l2_dev = &vpu->v4l2_dev;
346         vfd->vfl_dir = VFL_DIR_M2M;
347         vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
348         vfd->ioctl_ops = &rockchip_vpu_enc_ioctl_ops;
349         snprintf(vfd->name, sizeof(vfd->name), "%s-enc", match->compatible);
350         vpu->vfd_enc = vfd;
351         video_set_drvdata(vfd, vpu);
352
353         ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
354         if (ret) {
355                 v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n");
356                 goto err_free_dev;
357         }
358         v4l2_info(&vpu->v4l2_dev, "registered as /dev/video%d\n", vfd->num);
359
360         function = MEDIA_ENT_F_PROC_VIDEO_ENCODER;
361         ret = v4l2_m2m_register_media_controller(vpu->m2m_dev, vfd, function);
362         if (ret) {
363                 v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem media controller\n");
364                 goto err_unreg_video;
365         }
366         return 0;
367
368 err_unreg_video:
369         video_unregister_device(vfd);
370 err_free_dev:
371         video_device_release(vfd);
372         return ret;
373 }
374
375 static int rockchip_vpu_probe(struct platform_device *pdev)
376 {
377         const struct of_device_id *match;
378         struct rockchip_vpu_dev *vpu;
379         struct resource *res;
380         int i, ret;
381
382         vpu = devm_kzalloc(&pdev->dev, sizeof(*vpu), GFP_KERNEL);
383         if (!vpu)
384                 return -ENOMEM;
385
386         vpu->dev = &pdev->dev;
387         vpu->pdev = pdev;
388         mutex_init(&vpu->vpu_mutex);
389         spin_lock_init(&vpu->irqlock);
390
391         match = of_match_node(of_rockchip_vpu_match, pdev->dev.of_node);
392         vpu->variant = match->data;
393
394         INIT_DELAYED_WORK(&vpu->watchdog_work, rockchip_vpu_watchdog);
395
396         for (i = 0; i < vpu->variant->num_clocks; i++)
397                 vpu->clocks[i].id = vpu->variant->clk_names[i];
398         ret = devm_clk_bulk_get(&pdev->dev, vpu->variant->num_clocks,
399                                 vpu->clocks);
400         if (ret)
401                 return ret;
402
403         res = platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0);
404         vpu->base = devm_ioremap_resource(vpu->dev, res);
405         if (IS_ERR(vpu->base))
406                 return PTR_ERR(vpu->base);
407         vpu->enc_base = vpu->base + vpu->variant->enc_offset;
408
409         ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32));
410         if (ret) {
411                 dev_err(vpu->dev, "Could not set DMA coherent mask.\n");
412                 return ret;
413         }
414
415         if (vpu->variant->vepu_irq) {
416                 int irq;
417
418                 irq = platform_get_irq_byname(vpu->pdev, "vepu");
419                 if (irq <= 0) {
420                         dev_err(vpu->dev, "Could not get vepu IRQ.\n");
421                         return -ENXIO;
422                 }
423
424                 ret = devm_request_irq(vpu->dev, irq, vpu->variant->vepu_irq,
425                                        0, dev_name(vpu->dev), vpu);
426                 if (ret) {
427                         dev_err(vpu->dev, "Could not request vepu IRQ.\n");
428                         return ret;
429                 }
430         }
431
432         ret = vpu->variant->init(vpu);
433         if (ret) {
434                 dev_err(&pdev->dev, "Failed to init VPU hardware\n");
435                 return ret;
436         }
437
438         pm_runtime_set_autosuspend_delay(vpu->dev, 100);
439         pm_runtime_use_autosuspend(vpu->dev);
440         pm_runtime_enable(vpu->dev);
441
442         ret = clk_bulk_prepare(vpu->variant->num_clocks, vpu->clocks);
443         if (ret) {
444                 dev_err(&pdev->dev, "Failed to prepare clocks\n");
445                 return ret;
446         }
447
448         ret = v4l2_device_register(&pdev->dev, &vpu->v4l2_dev);
449         if (ret) {
450                 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
451                 goto err_clk_unprepare;
452         }
453         platform_set_drvdata(pdev, vpu);
454
455         vpu->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
456         if (IS_ERR(vpu->m2m_dev)) {
457                 v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem device\n");
458                 ret = PTR_ERR(vpu->m2m_dev);
459                 goto err_v4l2_unreg;
460         }
461
462         vpu->mdev.dev = vpu->dev;
463         strscpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model));
464         strscpy(vpu->mdev.bus_info, "platform: " DRIVER_NAME,
465                 sizeof(vpu->mdev.model));
466         media_device_init(&vpu->mdev);
467         vpu->v4l2_dev.mdev = &vpu->mdev;
468
469         ret = rockchip_vpu_video_device_register(vpu);
470         if (ret) {
471                 dev_err(&pdev->dev, "Failed to register encoder\n");
472                 goto err_m2m_rel;
473         }
474
475         ret = media_device_register(&vpu->mdev);
476         if (ret) {
477                 v4l2_err(&vpu->v4l2_dev, "Failed to register mem2mem media device\n");
478                 goto err_video_dev_unreg;
479         }
480         return 0;
481 err_video_dev_unreg:
482         if (vpu->vfd_enc) {
483                 v4l2_m2m_unregister_media_controller(vpu->m2m_dev);
484                 video_unregister_device(vpu->vfd_enc);
485                 video_device_release(vpu->vfd_enc);
486         }
487 err_m2m_rel:
488         media_device_cleanup(&vpu->mdev);
489         v4l2_m2m_release(vpu->m2m_dev);
490 err_v4l2_unreg:
491         v4l2_device_unregister(&vpu->v4l2_dev);
492 err_clk_unprepare:
493         clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
494         pm_runtime_dont_use_autosuspend(vpu->dev);
495         pm_runtime_disable(vpu->dev);
496         return ret;
497 }
498
499 static int rockchip_vpu_remove(struct platform_device *pdev)
500 {
501         struct rockchip_vpu_dev *vpu = platform_get_drvdata(pdev);
502
503         v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name);
504
505         media_device_unregister(&vpu->mdev);
506         if (vpu->vfd_enc) {
507                 v4l2_m2m_unregister_media_controller(vpu->m2m_dev);
508                 video_unregister_device(vpu->vfd_enc);
509                 video_device_release(vpu->vfd_enc);
510         }
511         media_device_cleanup(&vpu->mdev);
512         v4l2_m2m_release(vpu->m2m_dev);
513         v4l2_device_unregister(&vpu->v4l2_dev);
514         clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
515         pm_runtime_dont_use_autosuspend(vpu->dev);
516         pm_runtime_disable(vpu->dev);
517         return 0;
518 }
519
520 static const struct dev_pm_ops rockchip_vpu_pm_ops = {
521         SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
522                                 pm_runtime_force_resume)
523 };
524
525 static struct platform_driver rockchip_vpu_driver = {
526         .probe = rockchip_vpu_probe,
527         .remove = rockchip_vpu_remove,
528         .driver = {
529                    .name = DRIVER_NAME,
530                    .of_match_table = of_match_ptr(of_rockchip_vpu_match),
531                    .pm = &rockchip_vpu_pm_ops,
532         },
533 };
534 module_platform_driver(rockchip_vpu_driver);
535
536 MODULE_LICENSE("GPL v2");
537 MODULE_AUTHOR("Alpha Lin <Alpha.Lin@Rock-Chips.com>");
538 MODULE_AUTHOR("Tomasz Figa <tfiga@chromium.org>");
539 MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>");
540 MODULE_DESCRIPTION("Rockchip VPU codec driver");