1 /*
2 * Copyright 2022 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "hal_jpege_v540c"
18
19 #include <linux/string.h>
20
21 #include <string.h>
22 #include <math.h>
23 #include <limits.h>
24
25 #include "mpp_env.h"
26 #include "mpp_mem.h"
27 #include "mpp_soc.h"
28 #include "mpp_common.h"
29 #include "mpp_frame_impl.h"
30
31 #include "hal_jpege_debug.h"
32 #include "jpege_syntax.h"
33 #include "hal_bufs.h"
34 #include "rkv_enc_def.h"
35 #include "vepu541_common.h"
36 #include "vepu540c_common.h"
37 #include "hal_jpege_vepu540c.h"
38 #include "hal_jpege_vepu540c_reg.h"
39 #include "hal_jpege_hdr.h"
40
41 typedef struct jpegeV540cHalContext_t {
42 MppEncHalApi api;
43 MppDev dev;
44 void *regs;
45 void *reg_out;
46
47 void *dump_files;
48
49 RK_S32 frame_type;
50 RK_S32 last_frame_type;
51
52 /* @frame_cnt starts from ZERO */
53 RK_U32 frame_cnt;
54 void *roi_data;
55 MppEncCfgSet *cfg;
56
57 RK_U32 enc_mode;
58 RK_U32 frame_size;
59 RK_S32 max_buf_cnt;
60 RK_S32 hdr_status;
61 void *input_fmt;
62 RK_U8 *src_buf;
63 RK_U8 *dst_buf;
64 RK_S32 buf_size;
65 RK_U32 frame_num;
66 RK_S32 fbc_header_len;
67 RK_U32 title_num;
68
69 JpegeBits bits;
70 JpegeSyntax syntax;
71 } jpegeV540cHalContext;
72
hal_jpege_v540c_init(void * hal,MppEncHalCfg * cfg)73 MPP_RET hal_jpege_v540c_init(void *hal, MppEncHalCfg *cfg)
74 {
75 MPP_RET ret = MPP_OK;
76 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
77
78 mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
79
80 hal_jpege_enter();
81
82 ctx->reg_out = mpp_calloc(JpegV540cStatus, 1);
83 ctx->regs = mpp_calloc(JpegV540cRegSet, 1);
84 ctx->input_fmt = mpp_calloc(VepuFmtCfg, 1);
85 ctx->cfg = cfg->cfg;
86
87 ctx->frame_cnt = 0;
88 ctx->enc_mode = 1;
89 cfg->type = VPU_CLIENT_RKVENC;
90 ret = mpp_dev_init(&cfg->dev, cfg->type);
91 if (ret) {
92 mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
93 return ret;
94 }
95
96 ctx->dev = cfg->dev;
97 jpege_bits_init(&ctx->bits);
98 mpp_assert(ctx->bits);
99
100 hal_jpege_leave();
101 return ret;
102 }
103
hal_jpege_v540c_deinit(void * hal)104 MPP_RET hal_jpege_v540c_deinit(void *hal)
105 {
106 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
107
108 hal_jpege_enter();
109 jpege_bits_deinit(ctx->bits);
110 MPP_FREE(ctx->regs);
111
112 MPP_FREE(ctx->reg_out);
113
114 MPP_FREE(ctx->input_fmt);
115
116 if (ctx->dev) {
117 mpp_dev_deinit(ctx->dev);
118 ctx->dev = NULL;
119 }
120 hal_jpege_leave();
121 return MPP_OK;
122 }
123
hal_jpege_vepu540c_prepare(void * hal)124 static MPP_RET hal_jpege_vepu540c_prepare(void *hal)
125 {
126 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
127
128 hal_jpege_dbg_func("enter %p\n", hal);
129 VepuFmtCfg *fmt = (VepuFmtCfg *)ctx->input_fmt;
130 vepu541_set_fmt(fmt, ctx->cfg->prep.format);
131
132 hal_jpege_dbg_func("leave %p\n", hal);
133
134 return MPP_OK;
135 }
136
hal_jpege_v540c_gen_regs(void * hal,HalEncTask * task)137 MPP_RET hal_jpege_v540c_gen_regs(void *hal, HalEncTask *task)
138 {
139 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
140 JpegV540cRegSet *regs = ctx->regs;
141 jpeg_vepu540c_control_cfg *reg_ctl = ®s->reg_ctl;
142 jpeg_vepu540c_base *reg_base = ®s->reg_base;
143 JpegeBits bits = ctx->bits;
144 const RK_U8 *qtable[2] = {NULL};
145 size_t length = mpp_packet_get_length(task->packet);
146 RK_U8 *buf = mpp_buffer_get_ptr(task->output);
147 size_t size = mpp_buffer_get_size(task->output);
148 JpegeSyntax *syntax = &ctx->syntax;
149 Vepu540cJpegCfg cfg;
150 RK_S32 bitpos;
151
152 hal_jpege_enter();
153 cfg.enc_task = task;
154 cfg.jpeg_reg_base = ®_base->jpegReg;
155 cfg.dev = ctx->dev;
156 cfg.input_fmt = ctx->input_fmt;
157
158 memset(regs, 0, sizeof(JpegV540cRegSet));
159
160 /* write header to output buffer */
161 jpege_bits_setup(bits, buf, (RK_U32)size);
162 /* seek length bytes data */
163 jpege_seek_bits(bits, length << 3);
164 /* NOTE: write header will update qtable */
165 write_jpeg_header(bits, syntax, qtable);
166
167 bitpos = jpege_bits_get_bitpos(bits);
168 task->length = (bitpos + 7) >> 3;
169 mpp_packet_set_length(task->packet, task->length);
170 reg_ctl->reg0004_enc_strt.lkt_num = 0;
171 reg_ctl->reg0004_enc_strt.vepu_cmd = ctx->enc_mode;
172 reg_ctl->reg0005_enc_clr.safe_clr = 0x0;
173 reg_ctl->reg0005_enc_clr.force_clr = 0x0;
174
175 reg_ctl->reg0008_int_en.enc_done_en = 1;
176 reg_ctl->reg0008_int_en.lkt_node_done_en = 1;
177 reg_ctl->reg0008_int_en.sclr_done_en = 1;
178 reg_ctl->reg0008_int_en.slc_done_en = 1;
179 reg_ctl->reg0008_int_en.bsf_oflw_en = 1;
180 reg_ctl->reg0008_int_en.brsp_otsd_en = 1;
181 reg_ctl->reg0008_int_en.wbus_err_en = 1;
182 reg_ctl->reg0008_int_en.rbus_err_en = 1;
183 reg_ctl->reg0008_int_en.wdg_en = 1;
184 reg_ctl->reg0008_int_en.lkt_err_int_en = 0;
185
186 reg_ctl->reg0012_dtrns_map.jpeg_bus_edin = 0x7;
187 reg_ctl->reg0012_dtrns_map.src_bus_edin = 0x0;
188 reg_ctl->reg0012_dtrns_map.meiw_bus_edin = 0x0;
189 reg_ctl->reg0012_dtrns_map.bsw_bus_edin = 0x0;
190 reg_ctl->reg0012_dtrns_map.lktr_bus_edin = 0x0;
191 reg_ctl->reg0012_dtrns_map.roir_bus_edin = 0x0;
192 reg_ctl->reg0012_dtrns_map.lktw_bus_edin = 0x0;
193 reg_ctl->reg0012_dtrns_map.rec_nfbc_bus_edin = 0x0;
194 reg_base->reg0192_enc_pic.enc_stnd = 2; // disable h264 or hevc
195
196 reg_ctl->reg0013_dtrns_cfg.axi_brsp_cke = 0x0;
197 reg_ctl->reg0014_enc_wdg.vs_load_thd = 0x1fffff;
198 reg_ctl->reg0014_enc_wdg.rfp_load_thd = 0;
199
200 vepu540c_set_jpeg_reg(&cfg);
201 {
202 RK_U16 *tbl = ®s->jpeg_table.qua_tab0[0];
203 RK_U32 i, j;
204
205 for ( i = 0; i < 8; i++) {
206 for ( j = 0; j < 8; j++) {
207 tbl[i * 8 + j] = 0x8000 / qtable[0][j * 8 + i];
208 }
209 }
210 tbl += 64;
211 for ( i = 0; i < 8; i++) {
212 for ( j = 0; j < 8; j++) {
213 tbl[i * 8 + j] = 0x8000 / qtable[1][j * 8 + i];
214 }
215 }
216 tbl += 64;
217 for ( i = 0; i < 8; i++) {
218 for ( j = 0; j < 8; j++) {
219 tbl[i * 8 + j] = 0x8000 / qtable[1][j * 8 + i];
220 }
221 }
222 }
223 ctx->frame_num++;
224
225 hal_jpege_leave();
226 return MPP_OK;
227 }
228
hal_jpege_v540c_start(void * hal,HalEncTask * enc_task)229 MPP_RET hal_jpege_v540c_start(void *hal, HalEncTask *enc_task)
230 {
231 MPP_RET ret = MPP_OK;
232 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
233 JpegV540cRegSet *hw_regs = ctx->regs;
234 JpegV540cStatus *reg_out = ctx->reg_out;
235 MppDevRegWrCfg cfg;
236 MppDevRegRdCfg cfg1;
237 hal_jpege_enter();
238
239 if (enc_task->flags.err) {
240 mpp_err_f("enc_task->flags.err %08x, return e arly",
241 enc_task->flags.err);
242 return MPP_NOK;
243 }
244
245 cfg.reg = (RK_U32*)&hw_regs->reg_ctl;
246 cfg.size = sizeof(jpeg_vepu540c_control_cfg);
247 cfg.offset = VEPU540C_CTL_OFFSET;
248
249 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
250 if (ret) {
251 mpp_err_f("set register write failed %d\n", ret);
252 return ret;
253 }
254
255 cfg.reg = &hw_regs->jpeg_table;
256 cfg.size = sizeof(vepu540c_jpeg_tab);
257 cfg.offset = VEPU540C_JPEGTAB_OFFSET;
258
259 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
260 if (ret) {
261 mpp_err_f("set register write failed %d\n", ret);
262 return ret;
263 }
264
265 cfg.reg = &hw_regs->reg_base;
266 cfg.size = sizeof(jpeg_vepu540c_base);
267 cfg.offset = VEPU540C_BASE_OFFSET;
268
269 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
270 if (ret) {
271 mpp_err_f("set register write failed %d\n", ret);
272 return ret;
273 }
274
275 cfg1.reg = ®_out->hw_status;
276 cfg1.size = sizeof(RK_U32);
277 cfg1.offset = VEPU540C_REG_BASE_HW_STATUS;
278
279 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg1);
280 if (ret) {
281 mpp_err_f("set register read failed %d\n", ret);
282 return ret;
283 }
284
285 cfg1.reg = ®_out->st;
286 cfg1.size = sizeof(JpegV540cStatus) - 4;
287 cfg1.offset = VEPU540C_STATUS_OFFSET;
288
289 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg1);
290 if (ret) {
291 mpp_err_f("set register read failed %d\n", ret);
292 return ret;
293 }
294
295 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
296 if (ret) {
297 mpp_err_f("send cmd failed %d\n", ret);
298 }
299 hal_jpege_leave();
300 return ret;
301 }
302
303 //#define DUMP_DATA
hal_jpege_vepu540c_status_check(void * hal)304 static MPP_RET hal_jpege_vepu540c_status_check(void *hal)
305 {
306 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
307 JpegV540cStatus *elem = (JpegV540cStatus *)ctx->reg_out;
308
309 RK_U32 hw_status = elem->hw_status;
310
311 mpp_err_f("hw_status: 0x%08x", hw_status);
312 if (hw_status & RKV_ENC_INT_LINKTABLE_FINISH)
313 mpp_err_f("RKV_ENC_INT_LINKTABLE_FINISH");
314
315 if (hw_status & RKV_ENC_INT_ONE_FRAME_FINISH)
316 mpp_err_f("RKV_ENC_INT_ONE_FRAME_FINISH");
317
318 if (hw_status & RKV_ENC_INT_ONE_SLICE_FINISH)
319 mpp_err_f("RKV_ENC_INT_ONE_SLICE_FINISH");
320
321 if (hw_status & RKV_ENC_INT_SAFE_CLEAR_FINISH)
322 mpp_err_f("RKV_ENC_INT_SAFE_CLEAR_FINISH");
323
324 if (hw_status & RKV_ENC_INT_BIT_STREAM_OVERFLOW)
325 mpp_err_f("RKV_ENC_INT_BIT_STREAM_OVERFLOW");
326
327 if (hw_status & RKV_ENC_INT_BUS_WRITE_FULL)
328 mpp_err_f("RKV_ENC_INT_BUS_WRITE_FULL");
329
330 if (hw_status & RKV_ENC_INT_BUS_WRITE_ERROR)
331 mpp_err_f("RKV_ENC_INT_BUS_WRITE_ERROR");
332
333 if (hw_status & RKV_ENC_INT_BUS_READ_ERROR)
334 mpp_err_f("RKV_ENC_INT_BUS_READ_ERROR");
335
336 if (hw_status & RKV_ENC_INT_TIMEOUT_ERROR)
337 mpp_err_f("RKV_ENC_INT_TIMEOUT_ERROR");
338
339 return MPP_OK;
340 }
341
342
343
hal_jpege_v540c_wait(void * hal,HalEncTask * task)344 MPP_RET hal_jpege_v540c_wait(void *hal, HalEncTask *task)
345 {
346 MPP_RET ret = MPP_OK;
347 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
348 HalEncTask *enc_task = task;
349 JpegV540cStatus *elem = (JpegV540cStatus *)ctx->reg_out;
350 hal_jpege_enter();
351
352 if (enc_task->flags.err) {
353 mpp_err_f("enc_task->flags.err %08x, return early",
354 enc_task->flags.err);
355 return MPP_NOK;
356 }
357
358 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
359 if (ret) {
360 mpp_err_f("poll cmd failed %d\n", ret);
361 ret = MPP_ERR_VPUHW;
362 } else {
363 hal_jpege_vepu540c_status_check(hal);
364 task->hw_length += elem->st.jpeg_head_bits_l32;
365 }
366
367 hal_jpege_leave();
368 return ret;
369 }
370
hal_jpege_v540c_get_task(void * hal,HalEncTask * task)371 MPP_RET hal_jpege_v540c_get_task(void *hal, HalEncTask *task)
372 {
373 jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
374 MppFrame frame = task->frame;
375 EncFrmStatus *frm_status = &task->rc_task->frm;
376 JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
377
378 hal_jpege_enter();
379
380 memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
381
382 ctx->last_frame_type = ctx->frame_type;
383
384 if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
385 MppMeta meta = mpp_frame_get_meta(frame);
386
387 mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void **)&ctx->roi_data);
388 }
389
390 hal_jpege_leave();
391 return MPP_OK;
392 }
393
hal_jpege_v540c_ret_task(void * hal,HalEncTask * task)394 MPP_RET hal_jpege_v540c_ret_task(void *hal, HalEncTask *task)
395 {
396 (void)hal;
397 EncRcTaskInfo *rc_info = &task->rc_task->info;
398 hal_jpege_enter();
399
400 task->length += task->hw_length;
401
402 // setup bit length for rate control
403 rc_info->bit_real = task->hw_length * 8;
404 rc_info->quality_real = rc_info->quality_target;
405
406 hal_jpege_leave();
407 return MPP_OK;
408 }
409
410 const MppEncHalApi hal_jpege_vepu540c = {
411 "hal_jpege_v540c",
412 MPP_VIDEO_CodingMJPEG,
413 sizeof(jpegeV540cHalContext),
414 0,
415 hal_jpege_v540c_init,
416 hal_jpege_v540c_deinit,
417 hal_jpege_vepu540c_prepare,
418 hal_jpege_v540c_get_task,
419 hal_jpege_v540c_gen_regs,
420 hal_jpege_v540c_start,
421 hal_jpege_v540c_wait,
422 NULL,
423 NULL,
424 hal_jpege_v540c_ret_task,
425 };
426