treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174
[linux-2.6-block.git] / drivers / media / platform / mtk-vcodec / venc_vpu_if.c
CommitLineData
1802d0be 1// SPDX-License-Identifier: GPL-2.0-only
27a274db
TL
2/*
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: PoChun Lin <pochun.lin@mediatek.com>
27a274db
TL
5 */
6
7#include "mtk_vpu.h"
8#include "venc_ipi_msg.h"
9#include "venc_vpu_if.h"
10
11static void handle_enc_init_msg(struct venc_vpu_inst *vpu, void *data)
12{
13 struct venc_vpu_ipi_msg_init *msg = data;
14
15 vpu->inst_addr = msg->vpu_inst_addr;
16 vpu->vsi = vpu_mapping_dm_addr(vpu->dev, msg->vpu_inst_addr);
17}
18
19static void handle_enc_encode_msg(struct venc_vpu_inst *vpu, void *data)
20{
21 struct venc_vpu_ipi_msg_enc *msg = data;
22
23 vpu->state = msg->state;
24 vpu->bs_size = msg->bs_size;
25 vpu->is_key_frm = msg->is_key_frm;
26}
27
28static void vpu_enc_ipi_handler(void *data, unsigned int len, void *priv)
29{
30 struct venc_vpu_ipi_msg_common *msg = data;
65ad26cd
HV
31 struct venc_vpu_inst *vpu =
32 (struct venc_vpu_inst *)(unsigned long)msg->venc_inst;
27a274db
TL
33
34 mtk_vcodec_debug(vpu, "msg_id %x inst %p status %d",
35 msg->msg_id, vpu, msg->status);
36
37 switch (msg->msg_id) {
38 case VPU_IPIMSG_ENC_INIT_DONE:
39 handle_enc_init_msg(vpu, data);
40 break;
41 case VPU_IPIMSG_ENC_SET_PARAM_DONE:
42 break;
43 case VPU_IPIMSG_ENC_ENCODE_DONE:
44 handle_enc_encode_msg(vpu, data);
45 break;
46 case VPU_IPIMSG_ENC_DEINIT_DONE:
47 break;
48 default:
49 mtk_vcodec_err(vpu, "unknown msg id %x", msg->msg_id);
50 break;
51 }
52
53 vpu->signaled = 1;
54 vpu->failure = (msg->status != VENC_IPI_MSG_STATUS_OK);
55
56 mtk_vcodec_debug_leave(vpu);
57}
58
59static int vpu_enc_send_msg(struct venc_vpu_inst *vpu, void *msg,
60 int len)
61{
62 int status;
63
64 mtk_vcodec_debug_enter(vpu);
65
66 if (!vpu->dev) {
67 mtk_vcodec_err(vpu, "inst dev is NULL");
68 return -EINVAL;
69 }
70
71 status = vpu_ipi_send(vpu->dev, vpu->id, msg, len);
72 if (status) {
27a274db 73 mtk_vcodec_err(vpu, "vpu_ipi_send msg_id %x len %d fail %d",
9eeb0ed0 74 *(uint32_t *)msg, len, status);
27a274db
TL
75 return -EINVAL;
76 }
77 if (vpu->failure)
78 return -EINVAL;
79
80 mtk_vcodec_debug_leave(vpu);
81
82 return 0;
83}
84
85int vpu_enc_init(struct venc_vpu_inst *vpu)
86{
87 int status;
88 struct venc_ap_ipi_msg_init out;
89
90 mtk_vcodec_debug_enter(vpu);
91
92 init_waitqueue_head(&vpu->wq_hd);
93 vpu->signaled = 0;
94 vpu->failure = 0;
95
96 status = vpu_ipi_register(vpu->dev, vpu->id, vpu_enc_ipi_handler,
97 NULL, NULL);
98 if (status) {
99 mtk_vcodec_err(vpu, "vpu_ipi_register fail %d", status);
100 return -EINVAL;
101 }
102
103 memset(&out, 0, sizeof(out));
104 out.msg_id = AP_IPIMSG_ENC_INIT;
105 out.venc_inst = (unsigned long)vpu;
106 if (vpu_enc_send_msg(vpu, &out, sizeof(out))) {
107 mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_INIT fail");
108 return -EINVAL;
109 }
110
111 mtk_vcodec_debug_leave(vpu);
112
113 return 0;
114}
115
116int vpu_enc_set_param(struct venc_vpu_inst *vpu,
117 enum venc_set_param_type id,
118 struct venc_enc_param *enc_param)
119{
120 struct venc_ap_ipi_msg_set_param out;
121
122 mtk_vcodec_debug(vpu, "id %d ->", id);
123
124 memset(&out, 0, sizeof(out));
125 out.msg_id = AP_IPIMSG_ENC_SET_PARAM;
126 out.vpu_inst_addr = vpu->inst_addr;
127 out.param_id = id;
128 switch (id) {
129 case VENC_SET_PARAM_ENC:
130 out.data_item = 0;
131 break;
132 case VENC_SET_PARAM_FORCE_INTRA:
133 out.data_item = 0;
134 break;
135 case VENC_SET_PARAM_ADJUST_BITRATE:
136 out.data_item = 1;
137 out.data[0] = enc_param->bitrate;
138 break;
139 case VENC_SET_PARAM_ADJUST_FRAMERATE:
140 out.data_item = 1;
141 out.data[0] = enc_param->frm_rate;
142 break;
143 case VENC_SET_PARAM_GOP_SIZE:
144 out.data_item = 1;
145 out.data[0] = enc_param->gop_size;
146 break;
147 case VENC_SET_PARAM_INTRA_PERIOD:
148 out.data_item = 1;
149 out.data[0] = enc_param->intra_period;
150 break;
151 case VENC_SET_PARAM_SKIP_FRAME:
152 out.data_item = 0;
153 break;
154 default:
155 mtk_vcodec_err(vpu, "id %d not supported", id);
156 return -EINVAL;
157 }
158 if (vpu_enc_send_msg(vpu, &out, sizeof(out))) {
159 mtk_vcodec_err(vpu,
160 "AP_IPIMSG_ENC_SET_PARAM %d fail", id);
161 return -EINVAL;
162 }
163
164 mtk_vcodec_debug(vpu, "id %d <-", id);
165
166 return 0;
167}
168
169int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
170 struct venc_frm_buf *frm_buf,
171 struct mtk_vcodec_mem *bs_buf,
172 unsigned int *bs_size)
173{
174 struct venc_ap_ipi_msg_enc out;
175
176 mtk_vcodec_debug(vpu, "bs_mode %d ->", bs_mode);
177
178 memset(&out, 0, sizeof(out));
179 out.msg_id = AP_IPIMSG_ENC_ENCODE;
180 out.vpu_inst_addr = vpu->inst_addr;
181 out.bs_mode = bs_mode;
182 if (frm_buf) {
183 if ((frm_buf->fb_addr[0].dma_addr % 16 == 0) &&
184 (frm_buf->fb_addr[1].dma_addr % 16 == 0) &&
185 (frm_buf->fb_addr[2].dma_addr % 16 == 0)) {
186 out.input_addr[0] = frm_buf->fb_addr[0].dma_addr;
187 out.input_addr[1] = frm_buf->fb_addr[1].dma_addr;
188 out.input_addr[2] = frm_buf->fb_addr[2].dma_addr;
189 } else {
190 mtk_vcodec_err(vpu, "dma_addr not align to 16");
191 return -EINVAL;
192 }
193 }
194 if (bs_buf) {
195 out.bs_addr = bs_buf->dma_addr;
196 out.bs_size = bs_buf->size;
197 }
198 if (vpu_enc_send_msg(vpu, &out, sizeof(out))) {
199 mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail",
200 bs_mode);
201 return -EINVAL;
202 }
203
204 mtk_vcodec_debug(vpu, "bs_mode %d state %d size %d key_frm %d <-",
205 bs_mode, vpu->state, vpu->bs_size, vpu->is_key_frm);
206
207 return 0;
208}
209
210int vpu_enc_deinit(struct venc_vpu_inst *vpu)
211{
212 struct venc_ap_ipi_msg_deinit out;
213
214 mtk_vcodec_debug_enter(vpu);
215
216 memset(&out, 0, sizeof(out));
217 out.msg_id = AP_IPIMSG_ENC_DEINIT;
218 out.vpu_inst_addr = vpu->inst_addr;
219 if (vpu_enc_send_msg(vpu, &out, sizeof(out))) {
220 mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_DEINIT fail");
221 return -EINVAL;
222 }
223
224 mtk_vcodec_debug_leave(vpu);
225
226 return 0;
227}