xref: /OK3568_Linux_fs/external/mpp/mpp/hal/rkenc/jpege/hal_jpege_vepu540c.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 = &regs->reg_ctl;
142     jpeg_vepu540c_base *reg_base = &regs->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 = &reg_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 = &regs->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 = &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 = &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