xref: /rockchip-linux_mpp/mpp/hal/rkenc/jpege/hal_jpege_vepu540c.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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 "vepu5xx_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     HalJpegeRc          hal_rc;
72 } jpegeV540cHalContext;
73 
hal_jpege_v540c_init(void * hal,MppEncHalCfg * cfg)74 MPP_RET hal_jpege_v540c_init(void *hal, MppEncHalCfg *cfg)
75 {
76     MPP_RET ret = MPP_OK;
77     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
78 
79     mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
80 
81     hal_jpege_enter();
82 
83     ctx->reg_out  = mpp_calloc(JpegV540cStatus, 1);
84     ctx->regs           = mpp_calloc(JpegV540cRegSet, 1);
85     ctx->input_fmt      = mpp_calloc(VepuFmtCfg, 1);
86     ctx->cfg            = cfg->cfg;
87 
88     ctx->frame_cnt = 0;
89     ctx->enc_mode = 1;
90     cfg->type = VPU_CLIENT_RKVENC;
91     ret = mpp_dev_init(&cfg->dev, cfg->type);
92     if (ret) {
93         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
94         return ret;
95     }
96 
97     ctx->dev = cfg->dev;
98     jpege_bits_init(&ctx->bits);
99     mpp_assert(ctx->bits);
100     hal_jpege_rc_init(&ctx->hal_rc);
101 
102     hal_jpege_leave();
103     return ret;
104 }
105 
hal_jpege_v540c_deinit(void * hal)106 MPP_RET hal_jpege_v540c_deinit(void *hal)
107 {
108     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
109 
110     hal_jpege_enter();
111     jpege_bits_deinit(ctx->bits);
112     MPP_FREE(ctx->regs);
113 
114     MPP_FREE(ctx->reg_out);
115 
116     MPP_FREE(ctx->input_fmt);
117 
118     if (ctx->dev) {
119         mpp_dev_deinit(ctx->dev);
120         ctx->dev = NULL;
121     }
122     hal_jpege_leave();
123     return MPP_OK;
124 }
125 
hal_jpege_vepu540c_prepare(void * hal)126 static MPP_RET hal_jpege_vepu540c_prepare(void *hal)
127 {
128     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
129 
130     hal_jpege_dbg_func("enter %p\n", hal);
131     VepuFmtCfg *fmt = (VepuFmtCfg *)ctx->input_fmt;
132     vepu5xx_set_fmt(fmt, ctx->cfg->prep.format);
133 
134     hal_jpege_dbg_func("leave %p\n", hal);
135 
136     return MPP_OK;
137 }
138 
hal_jpege_v540c_gen_regs(void * hal,HalEncTask * task)139 MPP_RET hal_jpege_v540c_gen_regs(void *hal, HalEncTask *task)
140 {
141     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
142     JpegV540cRegSet *regs = ctx->regs;
143     jpeg_vepu540c_control_cfg *reg_ctl = &regs->reg_ctl;
144     jpeg_vepu540c_base *reg_base = &regs->reg_base;
145     JpegeBits bits = ctx->bits;
146     size_t length = mpp_packet_get_length(task->packet);
147     RK_U8  *buf = mpp_buffer_get_ptr(task->output);
148     size_t size = mpp_buffer_get_size(task->output);
149     JpegeSyntax *syntax = &ctx->syntax;
150     Vepu540cJpegCfg cfg;
151     RK_S32 bitpos;
152 
153     hal_jpege_enter();
154     cfg.enc_task = task;
155     cfg.jpeg_reg_base = &reg_base->jpegReg;
156     cfg.dev = ctx->dev;
157     cfg.input_fmt = ctx->input_fmt;
158 
159     memset(regs, 0, sizeof(JpegV540cRegSet));
160 
161     if (syntax->q_mode == JPEG_QFACTOR) {
162         syntax->q_factor = 100 - task->rc_task->info.quality_target;
163         hal_jpege_rc_update(&ctx->hal_rc, syntax);
164     }
165 
166     /* write header to output buffer */
167     jpege_bits_setup(bits, buf, (RK_U32)size);
168     /* seek length bytes data */
169     jpege_seek_bits(bits, length << 3);
170     /* NOTE: write header will update qtable */
171     write_jpeg_header(bits, syntax, &ctx->hal_rc);
172 
173     bitpos = jpege_bits_get_bitpos(bits);
174     task->length = (bitpos + 7) >> 3;
175     mpp_buffer_sync_partial_end(task->output, 0, task->length);
176     mpp_packet_set_length(task->packet, task->length);
177     reg_ctl->reg0004_enc_strt.lkt_num      = 0;
178     reg_ctl->reg0004_enc_strt.vepu_cmd     = ctx->enc_mode;
179     reg_ctl->reg0005_enc_clr.safe_clr      = 0x0;
180     reg_ctl->reg0005_enc_clr.force_clr     = 0x0;
181 
182     reg_ctl->reg0008_int_en.enc_done_en         = 1;
183     reg_ctl->reg0008_int_en.lkt_node_done_en    = 1;
184     reg_ctl->reg0008_int_en.sclr_done_en        = 1;
185     reg_ctl->reg0008_int_en.slc_done_en         = 1;
186     reg_ctl->reg0008_int_en.bsf_oflw_en         = 1;
187     reg_ctl->reg0008_int_en.brsp_otsd_en        = 1;
188     reg_ctl->reg0008_int_en.wbus_err_en         = 1;
189     reg_ctl->reg0008_int_en.rbus_err_en         = 1;
190     reg_ctl->reg0008_int_en.wdg_en              = 1;
191     reg_ctl->reg0008_int_en.lkt_err_int_en      = 0;
192 
193     reg_ctl->reg0012_dtrns_map.jpeg_bus_edin    = 0x7;
194     reg_ctl->reg0012_dtrns_map.src_bus_edin     = 0x0;
195     reg_ctl->reg0012_dtrns_map.meiw_bus_edin    = 0x0;
196     reg_ctl->reg0012_dtrns_map.bsw_bus_edin     = 0x0;
197     reg_ctl->reg0012_dtrns_map.lktr_bus_edin    = 0x0;
198     reg_ctl->reg0012_dtrns_map.roir_bus_edin    = 0x0;
199     reg_ctl->reg0012_dtrns_map.lktw_bus_edin    = 0x0;
200     reg_ctl->reg0012_dtrns_map.rec_nfbc_bus_edin   = 0x0;
201     reg_base->reg0192_enc_pic.enc_stnd = 2; // disable h264 or hevc
202 
203     reg_ctl->reg0013_dtrns_cfg.axi_brsp_cke     = 0x0;
204     reg_ctl->reg0014_enc_wdg.vs_load_thd        = 0x1fffff;
205     reg_ctl->reg0014_enc_wdg.rfp_load_thd       = 0;
206 
207     vepu540c_set_jpeg_reg(&cfg);
208     {
209         RK_U16 *tbl = &regs->jpeg_table.qua_tab0[0];
210         RK_U32 i, j;
211 
212         for ( i = 0; i < 8; i++) {
213             for ( j = 0; j < 8; j++) {
214                 tbl[i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[0][j * 8 + i];
215             }
216         }
217         tbl += 64;
218         for ( i = 0; i < 8; i++) {
219             for ( j = 0; j < 8; j++) {
220                 tbl[i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[1][j * 8 + i];
221             }
222         }
223         tbl += 64;
224         for ( i = 0; i < 8; i++) {
225             for ( j = 0; j < 8; j++) {
226                 tbl[i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[1][j * 8 + i];
227             }
228         }
229     }
230     ctx->frame_num++;
231 
232     hal_jpege_leave();
233     return MPP_OK;
234 }
235 
hal_jpege_v540c_start(void * hal,HalEncTask * enc_task)236 MPP_RET hal_jpege_v540c_start(void *hal, HalEncTask *enc_task)
237 {
238     MPP_RET ret = MPP_OK;
239     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
240     JpegV540cRegSet *hw_regs = ctx->regs;
241     JpegV540cStatus *reg_out = ctx->reg_out;
242     MppDevRegWrCfg cfg;
243     MppDevRegRdCfg cfg1;
244     hal_jpege_enter();
245 
246     if (enc_task->flags.err) {
247         mpp_err_f("enc_task->flags.err %08x, return e arly",
248                   enc_task->flags.err);
249         return MPP_NOK;
250     }
251 
252     cfg.reg = (RK_U32*)&hw_regs->reg_ctl;
253     cfg.size = sizeof(jpeg_vepu540c_control_cfg);
254     cfg.offset = VEPU540C_CTL_OFFSET;
255 
256     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
257     if (ret) {
258         mpp_err_f("set register write failed %d\n", ret);
259         return ret;
260     }
261 
262     cfg.reg = &hw_regs->jpeg_table;
263     cfg.size = sizeof(vepu540c_jpeg_tab);
264     cfg.offset = VEPU540C_JPEGTAB_OFFSET;
265 
266     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
267     if (ret) {
268         mpp_err_f("set register write failed %d\n", ret);
269         return ret;
270     }
271 
272     cfg.reg = &hw_regs->reg_base;
273     cfg.size = sizeof(jpeg_vepu540c_base);
274     cfg.offset = VEPU540C_BASE_OFFSET;
275 
276     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
277     if (ret) {
278         mpp_err_f("set register write failed %d\n", ret);
279         return ret;
280     }
281 
282     cfg1.reg = &reg_out->hw_status;
283     cfg1.size = sizeof(RK_U32);
284     cfg1.offset = VEPU540C_REG_BASE_HW_STATUS;
285 
286     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg1);
287     if (ret) {
288         mpp_err_f("set register read failed %d\n", ret);
289         return ret;
290     }
291 
292     cfg1.reg = &reg_out->st;
293     cfg1.size = sizeof(JpegV540cStatus) - 4;
294     cfg1.offset = VEPU540C_STATUS_OFFSET;
295 
296     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg1);
297     if (ret) {
298         mpp_err_f("set register read failed %d\n", ret);
299         return ret;
300     }
301 
302     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
303     if (ret) {
304         mpp_err_f("send cmd failed %d\n", ret);
305     }
306     hal_jpege_leave();
307     return ret;
308 }
309 
310 //#define DUMP_DATA
hal_jpege_vepu540c_status_check(void * hal)311 static MPP_RET hal_jpege_vepu540c_status_check(void *hal)
312 {
313     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
314     JpegV540cStatus *elem = (JpegV540cStatus *)ctx->reg_out;
315 
316     vepu540c_hw_status hw_status = elem->hw_status;
317 
318     hal_jpege_dbg_detail("hw_status: 0x%08x", hw_status.val);
319     if (hw_status.int_sta.enc_done_sta)
320         hal_jpege_dbg_detail("RKV_ENC_INT_ENC_DONE");
321 
322     if (hw_status.int_sta.wdg_sta)
323         mpp_err_f("RKV_ENC_INT_WDG_TIMEOUT");
324 
325     if (hw_status.int_sta.jslc_done_sta)
326         hal_jpege_dbg_detail("RKV_ENC_INT_JSL_DONE");
327 
328     if (hw_status.int_sta.jbsf_oflw_sta)
329         mpp_err_f("RKV_ENC_INT_JBSF_OFLOW");
330 
331 
332     return MPP_OK;
333 }
334 
335 
336 
hal_jpege_v540c_wait(void * hal,HalEncTask * task)337 MPP_RET hal_jpege_v540c_wait(void *hal, HalEncTask *task)
338 {
339     MPP_RET ret = MPP_OK;
340     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
341     HalEncTask *enc_task = task;
342     JpegV540cStatus *elem = (JpegV540cStatus *)ctx->reg_out;
343     hal_jpege_enter();
344 
345     if (enc_task->flags.err) {
346         mpp_err_f("enc_task->flags.err %08x, return early",
347                   enc_task->flags.err);
348         return MPP_NOK;
349     }
350 
351     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
352     if (ret) {
353         mpp_err_f("poll cmd failed %d\n", ret);
354         ret = MPP_ERR_VPUHW;
355     } else {
356         hal_jpege_vepu540c_status_check(hal);
357         task->hw_length += elem->st.jpeg_head_bits_l32;
358     }
359 
360     hal_jpege_leave();
361     return ret;
362 }
363 
hal_jpege_v540c_get_task(void * hal,HalEncTask * task)364 MPP_RET hal_jpege_v540c_get_task(void *hal, HalEncTask *task)
365 {
366     jpegeV540cHalContext *ctx = (jpegeV540cHalContext *)hal;
367     MppFrame frame = task->frame;
368     EncFrmStatus  *frm_status = &task->rc_task->frm;
369     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
370 
371     hal_jpege_enter();
372 
373     memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
374 
375     ctx->last_frame_type = ctx->frame_type;
376 
377     if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
378         MppMeta meta = mpp_frame_get_meta(frame);
379 
380         mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void **)&ctx->roi_data);
381     }
382 
383     if (ctx->cfg->jpeg.update) {
384         hal_jpege_rc_update(&ctx->hal_rc, syntax);
385         ctx->cfg->jpeg.update = 0;
386     }
387     task->rc_task->frm.is_intra = 1;
388 
389     hal_jpege_leave();
390     return MPP_OK;
391 }
392 
hal_jpege_v540c_ret_task(void * hal,HalEncTask * task)393 MPP_RET hal_jpege_v540c_ret_task(void *hal, HalEncTask *task)
394 {
395     (void)hal;
396     EncRcTaskInfo *rc_info = &task->rc_task->info;
397     hal_jpege_enter();
398 
399     task->length += task->hw_length;
400 
401     // setup bit length for rate control
402     rc_info->bit_real = task->hw_length * 8;
403     rc_info->quality_real = rc_info->quality_target;
404 
405     hal_jpege_leave();
406     return MPP_OK;
407 }
408 
409 const MppEncHalApi hal_jpege_vepu540c = {
410     "hal_jpege_v540c",
411     MPP_VIDEO_CodingMJPEG,
412     sizeof(jpegeV540cHalContext),
413     0,
414     hal_jpege_v540c_init,
415     hal_jpege_v540c_deinit,
416     hal_jpege_vepu540c_prepare,
417     hal_jpege_v540c_get_task,
418     hal_jpege_v540c_gen_regs,
419     hal_jpege_v540c_start,
420     hal_jpege_v540c_wait,
421     NULL,
422     NULL,
423     hal_jpege_v540c_ret_task,
424 };
425