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
17int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
18{
19 int ret = 0;
20
21 switch (fourcc) {
22 case V4L2_PIX_FMT_H264_SLICE:
23 ctx->dec_if = &vdec_h264_slice_if;
24 break;
25 case V4L2_PIX_FMT_H264:
26 ctx->dec_if = &vdec_h264_if;
27 ctx->hw_id = MTK_VDEC_CORE;
28 break;
29 case V4L2_PIX_FMT_VP8:
30 ctx->dec_if = &vdec_vp8_if;
31 ctx->hw_id = MTK_VDEC_CORE;
32 break;
33 case V4L2_PIX_FMT_VP9:
34 ctx->dec_if = &vdec_vp9_if;
35 ctx->hw_id = MTK_VDEC_CORE;
36 break;
37 default:
38 return -EINVAL;
39 }
40
41 mtk_vdec_lock(ctx);
42 mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
43 ret = ctx->dec_if->init(ctx);
44 mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
45 mtk_vdec_unlock(ctx);
46
47 return ret;
48}
49
50int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
51 struct vdec_fb *fb, bool *res_chg)
52{
53 int ret = 0;
54
55 if (bs) {
56 if ((bs->dma_addr & 63) != 0) {
57 mtk_v4l2_err("bs dma_addr should 64 byte align");
58 return -EINVAL;
59 }
60 }
61
62 if (fb) {
63 if (((fb->base_y.dma_addr & 511) != 0) ||
64 ((fb->base_c.dma_addr & 511) != 0)) {
65 mtk_v4l2_err("frame buffer dma_addr should 512 byte align");
66 return -EINVAL;
67 }
68 }
69
70 if (!ctx->drv_handle)
71 return -EIO;
72
73 mtk_vdec_lock(ctx);
74
75 mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
76 mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
77 ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
78 mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
79 mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
80
81 mtk_vdec_unlock(ctx);
82
83 return ret;
84}
85
86int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type,
87 void *out)
88{
89 int ret = 0;
90
91 if (!ctx->drv_handle)
92 return -EIO;
93
94 mtk_vdec_lock(ctx);
95 ret = ctx->dec_if->get_param(ctx->drv_handle, type, out);
96 mtk_vdec_unlock(ctx);
97
98 return ret;
99}
100
101void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
102{
103 if (!ctx->drv_handle)
104 return;
105
106 mtk_vdec_lock(ctx);
107 mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
108 ctx->dec_if->deinit(ctx->drv_handle);
109 mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
110 mtk_vdec_unlock(ctx);
111
112 ctx->drv_handle = NULL;
113}
114