]> git.samba.org - sfrench/cifs-2.6.git/blob - drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
selinux: kill 'flags' argument in avc_has_perm_flags() and avc_audit()
[sfrench/cifs-2.6.git] / drivers / media / platform / mtk-vcodec / mtk_vcodec_dec_drv.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016 MediaTek Inc.
4  * Author: PC Chen <pc.chen@mediatek.com>
5  *         Tiffany Lin <tiffany.lin@mediatek.com>
6  */
7
8 #include <linux/slab.h>
9 #include <linux/interrupt.h>
10 #include <linux/irq.h>
11 #include <linux/module.h>
12 #include <linux/of_device.h>
13 #include <linux/of.h>
14 #include <media/v4l2-event.h>
15 #include <media/v4l2-mem2mem.h>
16 #include <media/videobuf2-dma-contig.h>
17
18 #include "mtk_vcodec_drv.h"
19 #include "mtk_vcodec_dec.h"
20 #include "mtk_vcodec_dec_pm.h"
21 #include "mtk_vcodec_intr.h"
22 #include "mtk_vcodec_util.h"
23 #include "mtk_vcodec_fw.h"
24
25 #define VDEC_HW_ACTIVE  0x10
26 #define VDEC_IRQ_CFG    0x11
27 #define VDEC_IRQ_CLR    0x10
28 #define VDEC_IRQ_CFG_REG        0xa4
29
30 module_param(mtk_v4l2_dbg_level, int, 0644);
31 module_param(mtk_vcodec_dbg, bool, 0644);
32
33 /* Wake up context wait_queue */
34 static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
35 {
36         ctx->int_cond = 1;
37         wake_up_interruptible(&ctx->queue);
38 }
39
40 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
41 {
42         struct mtk_vcodec_dev *dev = priv;
43         struct mtk_vcodec_ctx *ctx;
44         u32 cg_status = 0;
45         unsigned int dec_done_status = 0;
46         void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
47                                         VDEC_IRQ_CFG_REG;
48
49         ctx = mtk_vcodec_get_curr_ctx(dev);
50
51         /* check if HW active or not */
52         cg_status = readl(dev->reg_base[0]);
53         if ((cg_status & VDEC_HW_ACTIVE) != 0) {
54                 mtk_v4l2_err("DEC ISR, VDEC active is not 0x0 (0x%08x)",
55                              cg_status);
56                 return IRQ_HANDLED;
57         }
58
59         dec_done_status = readl(vdec_misc_addr);
60         ctx->irq_status = dec_done_status;
61         if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
62                 MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
63                 return IRQ_HANDLED;
64
65         /* clear interrupt */
66         writel((readl(vdec_misc_addr) | VDEC_IRQ_CFG),
67                 dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
68         writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
69                 dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
70
71         wake_up_ctx(ctx);
72
73         mtk_v4l2_debug(3,
74                         "mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
75                         ctx->id, dec_done_status);
76
77         return IRQ_HANDLED;
78 }
79
80 static int fops_vcodec_open(struct file *file)
81 {
82         struct mtk_vcodec_dev *dev = video_drvdata(file);
83         struct mtk_vcodec_ctx *ctx = NULL;
84         struct mtk_video_dec_buf *mtk_buf = NULL;
85         int ret = 0;
86         struct vb2_queue *src_vq;
87
88         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
89         if (!ctx)
90                 return -ENOMEM;
91         mtk_buf = kzalloc(sizeof(*mtk_buf), GFP_KERNEL);
92         if (!mtk_buf) {
93                 kfree(ctx);
94                 return -ENOMEM;
95         }
96
97         mutex_lock(&dev->dev_mutex);
98         ctx->empty_flush_buf = mtk_buf;
99         ctx->id = dev->id_counter++;
100         v4l2_fh_init(&ctx->fh, video_devdata(file));
101         file->private_data = &ctx->fh;
102         v4l2_fh_add(&ctx->fh);
103         INIT_LIST_HEAD(&ctx->list);
104         ctx->dev = dev;
105         init_waitqueue_head(&ctx->queue);
106         mutex_init(&ctx->lock);
107
108         ctx->type = MTK_INST_DECODER;
109         ret = mtk_vcodec_dec_ctrls_setup(ctx);
110         if (ret) {
111                 mtk_v4l2_err("Failed to setup mt vcodec controls");
112                 goto err_ctrls_setup;
113         }
114         ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_dec, ctx,
115                 &mtk_vcodec_dec_queue_init);
116         if (IS_ERR((__force void *)ctx->m2m_ctx)) {
117                 ret = PTR_ERR((__force void *)ctx->m2m_ctx);
118                 mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)",
119                         ret);
120                 goto err_m2m_ctx_init;
121         }
122         src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
123                                 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
124         ctx->empty_flush_buf->m2m_buf.vb.vb2_buf.vb2_queue = src_vq;
125         ctx->empty_flush_buf->lastframe = true;
126         mtk_vcodec_dec_set_default_params(ctx);
127
128         if (v4l2_fh_is_singular(&ctx->fh)) {
129                 mtk_vcodec_dec_pw_on(&dev->pm);
130                 /*
131                  * Does nothing if firmware was already loaded.
132                  */
133                 ret = mtk_vcodec_fw_load_firmware(dev->fw_handler);
134                 if (ret < 0) {
135                         /*
136                          * Return 0 if downloading firmware successfully,
137                          * otherwise it is failed
138                          */
139                         mtk_v4l2_err("failed to load firmware!");
140                         goto err_load_fw;
141                 }
142
143                 dev->dec_capability =
144                         mtk_vcodec_fw_get_vdec_capa(dev->fw_handler);
145                 mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability);
146         }
147
148         list_add(&ctx->list, &dev->ctx_list);
149
150         mutex_unlock(&dev->dev_mutex);
151         mtk_v4l2_debug(0, "%s decoder [%d]", dev_name(&dev->plat_dev->dev),
152                         ctx->id);
153         return ret;
154
155         /* Deinit when failure occurred */
156 err_load_fw:
157         v4l2_m2m_ctx_release(ctx->m2m_ctx);
158 err_m2m_ctx_init:
159         v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
160 err_ctrls_setup:
161         v4l2_fh_del(&ctx->fh);
162         v4l2_fh_exit(&ctx->fh);
163         kfree(ctx->empty_flush_buf);
164         kfree(ctx);
165         mutex_unlock(&dev->dev_mutex);
166
167         return ret;
168 }
169
170 static int fops_vcodec_release(struct file *file)
171 {
172         struct mtk_vcodec_dev *dev = video_drvdata(file);
173         struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
174
175         mtk_v4l2_debug(0, "[%d] decoder", ctx->id);
176         mutex_lock(&dev->dev_mutex);
177
178         /*
179          * Call v4l2_m2m_ctx_release before mtk_vcodec_dec_release. First, it
180          * makes sure the worker thread is not running after vdec_if_deinit.
181          * Second, the decoder will be flushed and all the buffers will be
182          * returned in stop_streaming.
183          */
184         v4l2_m2m_ctx_release(ctx->m2m_ctx);
185         mtk_vcodec_dec_release(ctx);
186
187         if (v4l2_fh_is_singular(&ctx->fh))
188                 mtk_vcodec_dec_pw_off(&dev->pm);
189         v4l2_fh_del(&ctx->fh);
190         v4l2_fh_exit(&ctx->fh);
191         v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
192
193         list_del_init(&ctx->list);
194         kfree(ctx->empty_flush_buf);
195         kfree(ctx);
196         mutex_unlock(&dev->dev_mutex);
197         return 0;
198 }
199
200 static const struct v4l2_file_operations mtk_vcodec_fops = {
201         .owner          = THIS_MODULE,
202         .open           = fops_vcodec_open,
203         .release        = fops_vcodec_release,
204         .poll           = v4l2_m2m_fop_poll,
205         .unlocked_ioctl = video_ioctl2,
206         .mmap           = v4l2_m2m_fop_mmap,
207 };
208
209 static int mtk_vcodec_probe(struct platform_device *pdev)
210 {
211         struct mtk_vcodec_dev *dev;
212         struct video_device *vfd_dec;
213         struct resource *res;
214         phandle rproc_phandle;
215         enum mtk_vcodec_fw_type fw_type;
216         int i, ret;
217
218         dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
219         if (!dev)
220                 return -ENOMEM;
221
222         INIT_LIST_HEAD(&dev->ctx_list);
223         dev->plat_dev = pdev;
224
225         if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
226                                   &rproc_phandle)) {
227                 fw_type = VPU;
228         } else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,scp",
229                                          &rproc_phandle)) {
230                 fw_type = SCP;
231         } else {
232                 mtk_v4l2_err("Could not get vdec IPI device");
233                 return -ENODEV;
234         }
235         dma_set_max_seg_size(&pdev->dev, UINT_MAX);
236
237         dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, DECODER);
238         if (IS_ERR(dev->fw_handler))
239                 return PTR_ERR(dev->fw_handler);
240
241         ret = mtk_vcodec_init_dec_pm(dev);
242         if (ret < 0) {
243                 dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
244                 goto err_dec_pm;
245         }
246
247         for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
248                 dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
249                 if (IS_ERR((__force void *)dev->reg_base[i])) {
250                         ret = PTR_ERR((__force void *)dev->reg_base[i]);
251                         goto err_res;
252                 }
253                 mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
254         }
255
256         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
257         if (res == NULL) {
258                 dev_err(&pdev->dev, "failed to get irq resource");
259                 ret = -ENOENT;
260                 goto err_res;
261         }
262
263         dev->dec_irq = platform_get_irq(pdev, 0);
264         irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
265         ret = devm_request_irq(&pdev->dev, dev->dec_irq,
266                         mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
267         if (ret) {
268                 dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
269                         dev->dec_irq,
270                         ret);
271                 goto err_res;
272         }
273
274         mutex_init(&dev->dec_mutex);
275         mutex_init(&dev->dev_mutex);
276         spin_lock_init(&dev->irqlock);
277
278         snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
279                 "[/MTK_V4L2_VDEC]");
280
281         ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
282         if (ret) {
283                 mtk_v4l2_err("v4l2_device_register err=%d", ret);
284                 goto err_res;
285         }
286
287         init_waitqueue_head(&dev->queue);
288
289         vfd_dec = video_device_alloc();
290         if (!vfd_dec) {
291                 mtk_v4l2_err("Failed to allocate video device");
292                 ret = -ENOMEM;
293                 goto err_dec_alloc;
294         }
295         vfd_dec->fops           = &mtk_vcodec_fops;
296         vfd_dec->ioctl_ops      = &mtk_vdec_ioctl_ops;
297         vfd_dec->release        = video_device_release;
298         vfd_dec->lock           = &dev->dev_mutex;
299         vfd_dec->v4l2_dev       = &dev->v4l2_dev;
300         vfd_dec->vfl_dir        = VFL_DIR_M2M;
301         vfd_dec->device_caps    = V4L2_CAP_VIDEO_M2M_MPLANE |
302                         V4L2_CAP_STREAMING;
303
304         snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s",
305                 MTK_VCODEC_DEC_NAME);
306         video_set_drvdata(vfd_dec, dev);
307         dev->vfd_dec = vfd_dec;
308         platform_set_drvdata(pdev, dev);
309
310         dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops);
311         if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
312                 mtk_v4l2_err("Failed to init mem2mem dec device");
313                 ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
314                 goto err_dec_mem_init;
315         }
316
317         dev->decode_workqueue =
318                 alloc_ordered_workqueue(MTK_VCODEC_DEC_NAME,
319                         WQ_MEM_RECLAIM | WQ_FREEZABLE);
320         if (!dev->decode_workqueue) {
321                 mtk_v4l2_err("Failed to create decode workqueue");
322                 ret = -EINVAL;
323                 goto err_event_workq;
324         }
325
326         ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0);
327         if (ret) {
328                 mtk_v4l2_err("Failed to register video device");
329                 goto err_dec_reg;
330         }
331
332         mtk_v4l2_debug(0, "decoder registered as /dev/video%d",
333                 vfd_dec->num);
334
335         return 0;
336
337 err_dec_reg:
338         destroy_workqueue(dev->decode_workqueue);
339 err_event_workq:
340         v4l2_m2m_release(dev->m2m_dev_dec);
341 err_dec_mem_init:
342         video_unregister_device(vfd_dec);
343 err_dec_alloc:
344         v4l2_device_unregister(&dev->v4l2_dev);
345 err_res:
346         mtk_vcodec_release_dec_pm(dev);
347 err_dec_pm:
348         mtk_vcodec_fw_release(dev->fw_handler);
349         return ret;
350 }
351
352 static const struct of_device_id mtk_vcodec_match[] = {
353         {.compatible = "mediatek,mt8173-vcodec-dec",},
354         {},
355 };
356
357 MODULE_DEVICE_TABLE(of, mtk_vcodec_match);
358
359 static int mtk_vcodec_dec_remove(struct platform_device *pdev)
360 {
361         struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
362
363         flush_workqueue(dev->decode_workqueue);
364         destroy_workqueue(dev->decode_workqueue);
365         if (dev->m2m_dev_dec)
366                 v4l2_m2m_release(dev->m2m_dev_dec);
367
368         if (dev->vfd_dec)
369                 video_unregister_device(dev->vfd_dec);
370
371         v4l2_device_unregister(&dev->v4l2_dev);
372         mtk_vcodec_release_dec_pm(dev);
373         mtk_vcodec_fw_release(dev->fw_handler);
374         return 0;
375 }
376
377 static struct platform_driver mtk_vcodec_dec_driver = {
378         .probe  = mtk_vcodec_probe,
379         .remove = mtk_vcodec_dec_remove,
380         .driver = {
381                 .name   = MTK_VCODEC_DEC_NAME,
382                 .of_match_table = mtk_vcodec_match,
383         },
384 };
385
386 module_platform_driver(mtk_vcodec_dec_driver);
387
388 MODULE_LICENSE("GPL v2");
389 MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");