1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: PoChun Lin <pochun.lin@mediatek.com>
8 #include "venc_ipi_msg.h"
9 #include "venc_vpu_if.h"
11 static void handle_enc_init_msg(struct venc_vpu_inst
*vpu
, void *data
)
13 struct venc_vpu_ipi_msg_init
*msg
= data
;
15 vpu
->inst_addr
= msg
->vpu_inst_addr
;
16 vpu
->vsi
= vpu_mapping_dm_addr(vpu
->dev
, msg
->vpu_inst_addr
);
19 static void handle_enc_encode_msg(struct venc_vpu_inst
*vpu
, void *data
)
21 struct venc_vpu_ipi_msg_enc
*msg
= data
;
23 vpu
->state
= msg
->state
;
24 vpu
->bs_size
= msg
->bs_size
;
25 vpu
->is_key_frm
= msg
->is_key_frm
;
28 static void vpu_enc_ipi_handler(void *data
, unsigned int len
, void *priv
)
30 struct venc_vpu_ipi_msg_common
*msg
= data
;
31 struct venc_vpu_inst
*vpu
=
32 (struct venc_vpu_inst
*)(unsigned long)msg
->venc_inst
;
34 mtk_vcodec_debug(vpu
, "msg_id %x inst %p status %d",
35 msg
->msg_id
, vpu
, msg
->status
);
37 switch (msg
->msg_id
) {
38 case VPU_IPIMSG_ENC_INIT_DONE
:
39 handle_enc_init_msg(vpu
, data
);
41 case VPU_IPIMSG_ENC_SET_PARAM_DONE
:
43 case VPU_IPIMSG_ENC_ENCODE_DONE
:
44 handle_enc_encode_msg(vpu
, data
);
46 case VPU_IPIMSG_ENC_DEINIT_DONE
:
49 mtk_vcodec_err(vpu
, "unknown msg id %x", msg
->msg_id
);
54 vpu
->failure
= (msg
->status
!= VENC_IPI_MSG_STATUS_OK
);
56 mtk_vcodec_debug_leave(vpu
);
59 static int vpu_enc_send_msg(struct venc_vpu_inst
*vpu
, void *msg
,
64 mtk_vcodec_debug_enter(vpu
);
67 mtk_vcodec_err(vpu
, "inst dev is NULL");
71 status
= vpu_ipi_send(vpu
->dev
, vpu
->id
, msg
, len
);
73 mtk_vcodec_err(vpu
, "vpu_ipi_send msg_id %x len %d fail %d",
74 *(uint32_t *)msg
, len
, status
);
80 mtk_vcodec_debug_leave(vpu
);
85 int vpu_enc_init(struct venc_vpu_inst
*vpu
)
88 struct venc_ap_ipi_msg_init out
;
90 mtk_vcodec_debug_enter(vpu
);
92 init_waitqueue_head(&vpu
->wq_hd
);
96 status
= vpu_ipi_register(vpu
->dev
, vpu
->id
, vpu_enc_ipi_handler
,
99 mtk_vcodec_err(vpu
, "vpu_ipi_register fail %d", status
);
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");
111 mtk_vcodec_debug_leave(vpu
);
116 int vpu_enc_set_param(struct venc_vpu_inst
*vpu
,
117 enum venc_set_param_type id
,
118 struct venc_enc_param
*enc_param
)
120 struct venc_ap_ipi_msg_set_param out
;
122 mtk_vcodec_debug(vpu
, "id %d ->", id
);
124 memset(&out
, 0, sizeof(out
));
125 out
.msg_id
= AP_IPIMSG_ENC_SET_PARAM
;
126 out
.vpu_inst_addr
= vpu
->inst_addr
;
129 case VENC_SET_PARAM_ENC
:
132 case VENC_SET_PARAM_FORCE_INTRA
:
135 case VENC_SET_PARAM_ADJUST_BITRATE
:
137 out
.data
[0] = enc_param
->bitrate
;
139 case VENC_SET_PARAM_ADJUST_FRAMERATE
:
141 out
.data
[0] = enc_param
->frm_rate
;
143 case VENC_SET_PARAM_GOP_SIZE
:
145 out
.data
[0] = enc_param
->gop_size
;
147 case VENC_SET_PARAM_INTRA_PERIOD
:
149 out
.data
[0] = enc_param
->intra_period
;
151 case VENC_SET_PARAM_SKIP_FRAME
:
155 mtk_vcodec_err(vpu
, "id %d not supported", id
);
158 if (vpu_enc_send_msg(vpu
, &out
, sizeof(out
))) {
160 "AP_IPIMSG_ENC_SET_PARAM %d fail", id
);
164 mtk_vcodec_debug(vpu
, "id %d <-", id
);
169 int 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
)
174 struct venc_ap_ipi_msg_enc out
;
176 mtk_vcodec_debug(vpu
, "bs_mode %d ->", bs_mode
);
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
;
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
;
190 mtk_vcodec_err(vpu
, "dma_addr not align to 16");
195 out
.bs_addr
= bs_buf
->dma_addr
;
196 out
.bs_size
= bs_buf
->size
;
198 if (vpu_enc_send_msg(vpu
, &out
, sizeof(out
))) {
199 mtk_vcodec_err(vpu
, "AP_IPIMSG_ENC_ENCODE %d fail",
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
);
210 int vpu_enc_deinit(struct venc_vpu_inst
*vpu
)
212 struct venc_ap_ipi_msg_deinit out
;
214 mtk_vcodec_debug_enter(vpu
);
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");
224 mtk_vcodec_debug_leave(vpu
);