GNU Linux-libre 4.9.306-gnu1
[releases.git] / drivers / media / platform / mtk-vcodec / venc_drv_if.c
1 /*
2  * Copyright (c) 2016 MediaTek Inc.
3  * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
4  *      Jungchang Tsao <jungchang.tsao@mediatek.com>
5  *      Tiffany Lin <tiffany.lin@mediatek.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/slab.h>
21
22 #include "venc_drv_base.h"
23 #include "venc_drv_if.h"
24
25 #include "mtk_vcodec_enc.h"
26 #include "mtk_vcodec_enc_pm.h"
27 #include "mtk_vpu.h"
28
29 const struct venc_common_if *get_h264_enc_comm_if(void);
30 const struct venc_common_if *get_vp8_enc_comm_if(void);
31
32 int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
33 {
34         int ret = 0;
35
36         switch (fourcc) {
37         case V4L2_PIX_FMT_VP8:
38                 ctx->enc_if = get_vp8_enc_comm_if();
39                 break;
40         case V4L2_PIX_FMT_H264:
41                 ctx->enc_if = get_h264_enc_comm_if();
42                 break;
43         default:
44                 return -EINVAL;
45         }
46
47         mtk_venc_lock(ctx);
48         mtk_vcodec_enc_clock_on(&ctx->dev->pm);
49         ret = ctx->enc_if->init(ctx, (unsigned long *)&ctx->drv_handle);
50         mtk_vcodec_enc_clock_off(&ctx->dev->pm);
51         mtk_venc_unlock(ctx);
52
53         return ret;
54 }
55
56 int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
57                 enum venc_set_param_type type, struct venc_enc_param *in)
58 {
59         int ret = 0;
60
61         mtk_venc_lock(ctx);
62         mtk_vcodec_enc_clock_on(&ctx->dev->pm);
63         ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
64         mtk_vcodec_enc_clock_off(&ctx->dev->pm);
65         mtk_venc_unlock(ctx);
66
67         return ret;
68 }
69
70 int venc_if_encode(struct mtk_vcodec_ctx *ctx,
71                    enum venc_start_opt opt, struct venc_frm_buf *frm_buf,
72                    struct mtk_vcodec_mem *bs_buf,
73                    struct venc_done_result *result)
74 {
75         int ret = 0;
76         unsigned long flags;
77
78         mtk_venc_lock(ctx);
79
80         spin_lock_irqsave(&ctx->dev->irqlock, flags);
81         ctx->dev->curr_ctx = ctx;
82         spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
83
84         mtk_vcodec_enc_clock_on(&ctx->dev->pm);
85         ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
86                                   bs_buf, result);
87         mtk_vcodec_enc_clock_off(&ctx->dev->pm);
88
89         spin_lock_irqsave(&ctx->dev->irqlock, flags);
90         ctx->dev->curr_ctx = NULL;
91         spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
92
93         mtk_venc_unlock(ctx);
94         return ret;
95 }
96
97 int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
98 {
99         int ret = 0;
100
101         if (ctx->drv_handle == 0)
102                 return 0;
103
104         mtk_venc_lock(ctx);
105         mtk_vcodec_enc_clock_on(&ctx->dev->pm);
106         ret = ctx->enc_if->deinit(ctx->drv_handle);
107         mtk_vcodec_enc_clock_off(&ctx->dev->pm);
108         mtk_venc_unlock(ctx);
109
110         ctx->drv_handle = 0;
111
112         return ret;
113 }