Merge tag 'v5.2-rc4' into media/master
[sfrench/cifs-2.6.git] / drivers / media / platform / mtk-vcodec / vdec_drv_if.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/interrupt.h>
9 #include <linux/kernel.h>
10 #include <linux/slab.h>
11
12 #include "vdec_drv_if.h"
13 #include "mtk_vcodec_dec.h"
14 #include "vdec_drv_base.h"
15 #include "mtk_vcodec_dec_pm.h"
16 #include "mtk_vpu.h"
17
18 const struct vdec_common_if *get_h264_dec_comm_if(void);
19 const struct vdec_common_if *get_vp8_dec_comm_if(void);
20 const struct vdec_common_if *get_vp9_dec_comm_if(void);
21
22 int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
23 {
24         int ret = 0;
25
26         switch (fourcc) {
27         case V4L2_PIX_FMT_H264:
28                 ctx->dec_if = get_h264_dec_comm_if();
29                 break;
30         case V4L2_PIX_FMT_VP8:
31                 ctx->dec_if = get_vp8_dec_comm_if();
32                 break;
33         case V4L2_PIX_FMT_VP9:
34                 ctx->dec_if = get_vp9_dec_comm_if();
35                 break;
36         default:
37                 return -EINVAL;
38         }
39
40         mtk_vdec_lock(ctx);
41         mtk_vcodec_dec_clock_on(&ctx->dev->pm);
42         ret = ctx->dec_if->init(ctx, &ctx->drv_handle);
43         mtk_vcodec_dec_clock_off(&ctx->dev->pm);
44         mtk_vdec_unlock(ctx);
45
46         return ret;
47 }
48
49 int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
50                    struct vdec_fb *fb, bool *res_chg)
51 {
52         int ret = 0;
53
54         if (bs) {
55                 if ((bs->dma_addr & 63) != 0) {
56                         mtk_v4l2_err("bs dma_addr should 64 byte align");
57                         return -EINVAL;
58                 }
59         }
60
61         if (fb) {
62                 if (((fb->base_y.dma_addr & 511) != 0) ||
63                     ((fb->base_c.dma_addr & 511) != 0)) {
64                         mtk_v4l2_err("frame buffer dma_addr should 512 byte align");
65                         return -EINVAL;
66                 }
67         }
68
69         if (ctx->drv_handle == 0)
70                 return -EIO;
71
72         mtk_vdec_lock(ctx);
73
74         mtk_vcodec_set_curr_ctx(ctx->dev, ctx);
75         mtk_vcodec_dec_clock_on(&ctx->dev->pm);
76         enable_irq(ctx->dev->dec_irq);
77         ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
78         disable_irq(ctx->dev->dec_irq);
79         mtk_vcodec_dec_clock_off(&ctx->dev->pm);
80         mtk_vcodec_set_curr_ctx(ctx->dev, NULL);
81
82         mtk_vdec_unlock(ctx);
83
84         return ret;
85 }
86
87 int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type,
88                       void *out)
89 {
90         int ret = 0;
91
92         if (ctx->drv_handle == 0)
93                 return -EIO;
94
95         mtk_vdec_lock(ctx);
96         ret = ctx->dec_if->get_param(ctx->drv_handle, type, out);
97         mtk_vdec_unlock(ctx);
98
99         return ret;
100 }
101
102 void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
103 {
104         if (ctx->drv_handle == 0)
105                 return;
106
107         mtk_vdec_lock(ctx);
108         mtk_vcodec_dec_clock_on(&ctx->dev->pm);
109         ctx->dec_if->deinit(ctx->drv_handle);
110         mtk_vcodec_dec_clock_off(&ctx->dev->pm);
111         mtk_vdec_unlock(ctx);
112
113         ctx->drv_handle = 0;
114 }