1
2
3
4
5
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
18const struct vdec_common_if *get_h264_dec_comm_if(void);
19const struct vdec_common_if *get_vp8_dec_comm_if(void);
20const struct vdec_common_if *get_vp9_dec_comm_if(void);
21
22int 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
49int 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
87int 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
102void 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}
115