xref: /rockchip-linux_mpp/mpp/hal/vpu/jpege/hal_jpege_vepu1_v2.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "hal_jpege_vepu1"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_env.h"
22*437bfbebSnyanmisaka #include "mpp_common.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_platform.h"
25*437bfbebSnyanmisaka 
26*437bfbebSnyanmisaka #include "mpp_enc_hal.h"
27*437bfbebSnyanmisaka #include "vcodec_service.h"
28*437bfbebSnyanmisaka 
29*437bfbebSnyanmisaka #include "hal_jpege_debug.h"
30*437bfbebSnyanmisaka #include "hal_jpege_api_v2.h"
31*437bfbebSnyanmisaka #include "hal_jpege_base.h"
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka #define VEPU_JPEGE_VEPU1_NUM_REGS 164
34*437bfbebSnyanmisaka 
35*437bfbebSnyanmisaka typedef struct jpege_vepu1_reg_set_t {
36*437bfbebSnyanmisaka     RK_U32  val[VEPU_JPEGE_VEPU1_NUM_REGS];
37*437bfbebSnyanmisaka } jpege_vepu1_reg_set;
38*437bfbebSnyanmisaka 
hal_jpege_vepu1_init(void * hal,MppEncHalCfg * cfg)39*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_init(void *hal, MppEncHalCfg *cfg)
40*437bfbebSnyanmisaka {
41*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
42*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
43*437bfbebSnyanmisaka 
44*437bfbebSnyanmisaka     mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
45*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p cfg %p\n", hal, cfg);
46*437bfbebSnyanmisaka 
47*437bfbebSnyanmisaka     /* update output to MppEnc */
48*437bfbebSnyanmisaka     cfg->type = VPU_CLIENT_VEPU1;
49*437bfbebSnyanmisaka     ret = mpp_dev_init(&cfg->dev, cfg->type);
50*437bfbebSnyanmisaka     if (ret) {
51*437bfbebSnyanmisaka         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
52*437bfbebSnyanmisaka         return ret;
53*437bfbebSnyanmisaka     }
54*437bfbebSnyanmisaka     ctx->dev = cfg->dev;
55*437bfbebSnyanmisaka 
56*437bfbebSnyanmisaka     jpege_bits_init(&ctx->bits);
57*437bfbebSnyanmisaka     mpp_assert(ctx->bits);
58*437bfbebSnyanmisaka 
59*437bfbebSnyanmisaka     ctx->cfg = cfg->cfg;
60*437bfbebSnyanmisaka     ctx->reg_size = sizeof(RK_U32) * VEPU_JPEGE_VEPU1_NUM_REGS;
61*437bfbebSnyanmisaka     ctx->regs = mpp_calloc_size(void, ctx->reg_size + EXTRA_INFO_SIZE);
62*437bfbebSnyanmisaka     if (NULL == ctx->regs) {
63*437bfbebSnyanmisaka         mpp_err_f("failed to malloc vepu1 regs\n");
64*437bfbebSnyanmisaka         return MPP_NOK;
65*437bfbebSnyanmisaka     }
66*437bfbebSnyanmisaka 
67*437bfbebSnyanmisaka     ctx->regs_out = mpp_calloc_size(void, ctx->reg_size + EXTRA_INFO_SIZE);
68*437bfbebSnyanmisaka     if (NULL == ctx->regs_out) {
69*437bfbebSnyanmisaka         mpp_err_f("failed to malloc vepu2 regs\n");
70*437bfbebSnyanmisaka         return MPP_NOK;
71*437bfbebSnyanmisaka     }
72*437bfbebSnyanmisaka 
73*437bfbebSnyanmisaka     hal_jpege_rc_init(&ctx->hal_rc);
74*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
75*437bfbebSnyanmisaka     return MPP_OK;
76*437bfbebSnyanmisaka }
77*437bfbebSnyanmisaka 
hal_jpege_vepu1_deinit(void * hal)78*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_deinit(void *hal)
79*437bfbebSnyanmisaka {
80*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
81*437bfbebSnyanmisaka 
82*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
83*437bfbebSnyanmisaka 
84*437bfbebSnyanmisaka     if (ctx->bits) {
85*437bfbebSnyanmisaka         jpege_bits_deinit(ctx->bits);
86*437bfbebSnyanmisaka         ctx->bits = NULL;
87*437bfbebSnyanmisaka     }
88*437bfbebSnyanmisaka 
89*437bfbebSnyanmisaka     if (ctx->dev) {
90*437bfbebSnyanmisaka         mpp_dev_deinit(ctx->dev);
91*437bfbebSnyanmisaka         ctx->dev = NULL;
92*437bfbebSnyanmisaka     }
93*437bfbebSnyanmisaka 
94*437bfbebSnyanmisaka     MPP_FREE(ctx->regs);
95*437bfbebSnyanmisaka     MPP_FREE(ctx->regs_out);
96*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
97*437bfbebSnyanmisaka     return MPP_OK;
98*437bfbebSnyanmisaka }
99*437bfbebSnyanmisaka 
hal_jpege_vepu1_get_task(void * hal,HalEncTask * task)100*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_get_task(void *hal, HalEncTask *task)
101*437bfbebSnyanmisaka {
102*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
103*437bfbebSnyanmisaka     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
104*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka     memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
107*437bfbebSnyanmisaka 
108*437bfbebSnyanmisaka     ctx->hal_start_pos = mpp_packet_get_length(task->packet);
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka     /* prepare for part encoding */
111*437bfbebSnyanmisaka     ctx->mcu_y = 0;
112*437bfbebSnyanmisaka     ctx->mcu_h = syntax->mcu_ver_cnt;
113*437bfbebSnyanmisaka     ctx->sw_bit = 0;
114*437bfbebSnyanmisaka     ctx->part_bytepos = 0;
115*437bfbebSnyanmisaka     ctx->part_x_fill = 0;
116*437bfbebSnyanmisaka     ctx->part_y_fill = 0;
117*437bfbebSnyanmisaka     task->part_first = 1;
118*437bfbebSnyanmisaka     task->part_last = 0;
119*437bfbebSnyanmisaka 
120*437bfbebSnyanmisaka     if (ctx->cfg->jpeg.update) {
121*437bfbebSnyanmisaka         hal_jpege_rc_update(&ctx->hal_rc, syntax);
122*437bfbebSnyanmisaka         ctx->cfg->jpeg.update = 0;
123*437bfbebSnyanmisaka     }
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka     task->rc_task->frm.is_intra = 1;
126*437bfbebSnyanmisaka 
127*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     return MPP_OK;
130*437bfbebSnyanmisaka }
131*437bfbebSnyanmisaka 
hal_jpege_vepu1_set_extra_info(MppDev dev,JpegeSyntax * syntax,RK_U32 start_mbrow)132*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_set_extra_info(MppDev dev, JpegeSyntax *syntax,
133*437bfbebSnyanmisaka                                               RK_U32 start_mbrow)
134*437bfbebSnyanmisaka {
135*437bfbebSnyanmisaka     MppFrameFormat fmt  = syntax->format;
136*437bfbebSnyanmisaka     RK_U32 hor_stride   = syntax->hor_stride;
137*437bfbebSnyanmisaka     RK_U32 ver_stride   = syntax->ver_stride;
138*437bfbebSnyanmisaka     RK_U32 offset = 0;
139*437bfbebSnyanmisaka 
140*437bfbebSnyanmisaka     switch (fmt) {
141*437bfbebSnyanmisaka     case MPP_FMT_YUV420SP :
142*437bfbebSnyanmisaka     case MPP_FMT_YUV420P : {
143*437bfbebSnyanmisaka         if (start_mbrow) {
144*437bfbebSnyanmisaka             offset = 16 * start_mbrow * hor_stride;
145*437bfbebSnyanmisaka 
146*437bfbebSnyanmisaka             mpp_dev_set_reg_offset(dev, 11, offset);
147*437bfbebSnyanmisaka         }
148*437bfbebSnyanmisaka 
149*437bfbebSnyanmisaka         offset = hor_stride * ver_stride + hor_stride * start_mbrow * 16 / 2;
150*437bfbebSnyanmisaka         if (fmt == MPP_FMT_YUV420P)
151*437bfbebSnyanmisaka             offset = hor_stride * start_mbrow * 16 / 4 + hor_stride * ver_stride;
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 12, offset);
154*437bfbebSnyanmisaka 
155*437bfbebSnyanmisaka         if (fmt == MPP_FMT_YUV420P)
156*437bfbebSnyanmisaka             offset = hor_stride * start_mbrow * 16 / 4 + hor_stride * ver_stride * 5 / 4;
157*437bfbebSnyanmisaka 
158*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 13, offset);
159*437bfbebSnyanmisaka     } break;
160*437bfbebSnyanmisaka     default : {
161*437bfbebSnyanmisaka         if (start_mbrow) {
162*437bfbebSnyanmisaka             offset = start_mbrow * hor_stride;
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka             mpp_dev_set_reg_offset(dev, 11, offset);
165*437bfbebSnyanmisaka         }
166*437bfbebSnyanmisaka     } break;
167*437bfbebSnyanmisaka     }
168*437bfbebSnyanmisaka 
169*437bfbebSnyanmisaka     return MPP_OK;
170*437bfbebSnyanmisaka }
171*437bfbebSnyanmisaka 
hal_jpege_vepu1_gen_regs(void * hal,HalEncTask * task)172*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_gen_regs(void *hal, HalEncTask *task)
173*437bfbebSnyanmisaka {
174*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
175*437bfbebSnyanmisaka     MppBuffer input  = task->input;
176*437bfbebSnyanmisaka     MppBuffer output = task->output;
177*437bfbebSnyanmisaka     JpegeSyntax *syntax = &ctx->syntax;
178*437bfbebSnyanmisaka     RK_U32 width        = syntax->width;
179*437bfbebSnyanmisaka     RK_U32 width_align  = MPP_ALIGN(width, 16);
180*437bfbebSnyanmisaka     RK_U32 height       = syntax->height;
181*437bfbebSnyanmisaka     MppFrameFormat fmt  = syntax->format;
182*437bfbebSnyanmisaka     RK_U32 hor_stride   = 0;
183*437bfbebSnyanmisaka     RK_U32 ver_stride   = MPP_ALIGN(height, 16);
184*437bfbebSnyanmisaka     JpegeBits bits      = ctx->bits;
185*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)ctx->regs;
186*437bfbebSnyanmisaka     size_t length = mpp_packet_get_length(task->packet);
187*437bfbebSnyanmisaka     RK_U8  *buf = mpp_buffer_get_ptr(output);
188*437bfbebSnyanmisaka     size_t size = mpp_buffer_get_size(output);
189*437bfbebSnyanmisaka     RK_S32 bitpos;
190*437bfbebSnyanmisaka     RK_S32 bytepos;
191*437bfbebSnyanmisaka     RK_U32 x_fill = 0;
192*437bfbebSnyanmisaka     RK_U32 y_fill = 0;
193*437bfbebSnyanmisaka     VepuFormatCfg fmt_cfg;
194*437bfbebSnyanmisaka     RK_U32 rotation = 0;
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
197*437bfbebSnyanmisaka 
198*437bfbebSnyanmisaka     // do not support mirroring
199*437bfbebSnyanmisaka     if (syntax->mirroring)
200*437bfbebSnyanmisaka         mpp_err_f("Warning: do not support mirroring\n");
201*437bfbebSnyanmisaka 
202*437bfbebSnyanmisaka     if (syntax->rotation == MPP_ENC_ROT_90)
203*437bfbebSnyanmisaka         rotation = 1;
204*437bfbebSnyanmisaka     else if (syntax->rotation == MPP_ENC_ROT_270)
205*437bfbebSnyanmisaka         rotation = 2;
206*437bfbebSnyanmisaka     else if (syntax->rotation != MPP_ENC_ROT_0)
207*437bfbebSnyanmisaka         mpp_err_f("Warning: only support 90 or 270 degree rotate, request rotate %d", syntax->rotation);
208*437bfbebSnyanmisaka     if (rotation) {
209*437bfbebSnyanmisaka         MPP_SWAP(RK_U32, width, height);
210*437bfbebSnyanmisaka         MPP_SWAP(RK_U32, width_align, ver_stride);
211*437bfbebSnyanmisaka     }
212*437bfbebSnyanmisaka 
213*437bfbebSnyanmisaka     hor_stride = get_vepu_pixel_stride(&ctx->stride_cfg, width,
214*437bfbebSnyanmisaka                                        syntax->hor_stride, fmt);
215*437bfbebSnyanmisaka 
216*437bfbebSnyanmisaka     //hor_stride must be align with 8, and ver_stride mus align with 2
217*437bfbebSnyanmisaka     if ((hor_stride & 0x7) || (ver_stride & 0x1) || (hor_stride >= (1 << 15))) {
218*437bfbebSnyanmisaka         mpp_err_f("illegal resolution, hor_stride %d, ver_stride %d, width %d, height %d\n",
219*437bfbebSnyanmisaka                   syntax->hor_stride, syntax->ver_stride,
220*437bfbebSnyanmisaka                   syntax->width, syntax->height);
221*437bfbebSnyanmisaka     }
222*437bfbebSnyanmisaka 
223*437bfbebSnyanmisaka     x_fill = (width_align - width) / 4;
224*437bfbebSnyanmisaka     y_fill = (ver_stride - height);
225*437bfbebSnyanmisaka     mpp_assert(x_fill <= 3);
226*437bfbebSnyanmisaka     mpp_assert(y_fill <= 15);
227*437bfbebSnyanmisaka     ctx->part_x_fill = x_fill;
228*437bfbebSnyanmisaka     ctx->part_y_fill = y_fill;
229*437bfbebSnyanmisaka 
230*437bfbebSnyanmisaka     mpp_buffer_sync_begin(output);
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka     if (syntax->q_mode == JPEG_QFACTOR) {
233*437bfbebSnyanmisaka         syntax->q_factor = 100 - task->rc_task->info.quality_target;
234*437bfbebSnyanmisaka         hal_jpege_rc_update(&ctx->hal_rc, syntax);
235*437bfbebSnyanmisaka     }
236*437bfbebSnyanmisaka     /* write header to output buffer */
237*437bfbebSnyanmisaka     jpege_bits_setup(bits, buf, (RK_U32)size);
238*437bfbebSnyanmisaka     /* seek length bytes data */
239*437bfbebSnyanmisaka     jpege_seek_bits(bits, length << 3);
240*437bfbebSnyanmisaka     /* NOTE: write header will update qtable */
241*437bfbebSnyanmisaka     write_jpeg_header(bits, syntax, &ctx->hal_rc);
242*437bfbebSnyanmisaka 
243*437bfbebSnyanmisaka     memset(regs, 0, sizeof(RK_U32) * VEPU_JPEGE_VEPU1_NUM_REGS);
244*437bfbebSnyanmisaka     regs[11] = mpp_buffer_get_fd(input);
245*437bfbebSnyanmisaka     regs[12] = mpp_buffer_get_fd(input);
246*437bfbebSnyanmisaka     regs[13] = regs[12];
247*437bfbebSnyanmisaka 
248*437bfbebSnyanmisaka     bitpos = jpege_bits_get_bitpos(bits);
249*437bfbebSnyanmisaka     bytepos = (bitpos + 7) >> 3;
250*437bfbebSnyanmisaka     ctx->base = buf;
251*437bfbebSnyanmisaka     ctx->size = size;
252*437bfbebSnyanmisaka     ctx->sw_bit = bitpos;
253*437bfbebSnyanmisaka     ctx->part_bytepos = bytepos;
254*437bfbebSnyanmisaka 
255*437bfbebSnyanmisaka     get_msb_lsb_at_pos(&regs[22], &regs[23], buf, bytepos);
256*437bfbebSnyanmisaka 
257*437bfbebSnyanmisaka     mpp_buffer_sync_end(output);
258*437bfbebSnyanmisaka 
259*437bfbebSnyanmisaka     if (!get_vepu_fmt(&fmt_cfg, fmt)) {
260*437bfbebSnyanmisaka         RK_U32 deflt_cfg = ((0  & (255)) << 24) |
261*437bfbebSnyanmisaka                            ((0  & (255)) << 16) |
262*437bfbebSnyanmisaka                            ((1  & (1)) << 15) |
263*437bfbebSnyanmisaka                            ((16 & (63)) << 8) |
264*437bfbebSnyanmisaka                            ((0  & (1)) << 6) |
265*437bfbebSnyanmisaka                            ((0  & (1)) << 5) |
266*437bfbebSnyanmisaka                            ((1  & (1)) << 4) |
267*437bfbebSnyanmisaka                            ((1  & (1)) << 3) |
268*437bfbebSnyanmisaka                            ((1  & (1)) << 1);
269*437bfbebSnyanmisaka 
270*437bfbebSnyanmisaka         regs[2] = deflt_cfg | (fmt_cfg.swap_8_in & 1) |
271*437bfbebSnyanmisaka                   (fmt_cfg.swap_32_in & 1) << 2 |
272*437bfbebSnyanmisaka                   (fmt_cfg.swap_16_in & 1) << 14;
273*437bfbebSnyanmisaka     }
274*437bfbebSnyanmisaka 
275*437bfbebSnyanmisaka     regs[5] = mpp_buffer_get_fd(output);
276*437bfbebSnyanmisaka     if (bytepos)
277*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(ctx->dev, 5, bytepos);
278*437bfbebSnyanmisaka 
279*437bfbebSnyanmisaka     regs[14] = (1 << 31) |
280*437bfbebSnyanmisaka                (0 << 30) |
281*437bfbebSnyanmisaka                (0 << 29) |
282*437bfbebSnyanmisaka                ((width_align >> 4) << 19) |
283*437bfbebSnyanmisaka                ((ver_stride >> 4) << 10) |
284*437bfbebSnyanmisaka                (1 << 3) | (2 << 1);
285*437bfbebSnyanmisaka 
286*437bfbebSnyanmisaka     regs[15] = (0 << 29) |
287*437bfbebSnyanmisaka                (0 << 26) |
288*437bfbebSnyanmisaka                (hor_stride << 12) |
289*437bfbebSnyanmisaka                (x_fill << 10) |
290*437bfbebSnyanmisaka                (y_fill << 6) |
291*437bfbebSnyanmisaka                (fmt_cfg.format << 2) | rotation;
292*437bfbebSnyanmisaka 
293*437bfbebSnyanmisaka     regs[24] = size - bytepos;
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka     regs[37] = ((bytepos & 7) * 8) << 23;
296*437bfbebSnyanmisaka 
297*437bfbebSnyanmisaka     {
298*437bfbebSnyanmisaka         RK_U32 coeffA;
299*437bfbebSnyanmisaka         RK_U32 coeffB;
300*437bfbebSnyanmisaka         RK_U32 coeffC;
301*437bfbebSnyanmisaka         RK_U32 coeffE;
302*437bfbebSnyanmisaka         RK_U32 coeffF;
303*437bfbebSnyanmisaka 
304*437bfbebSnyanmisaka         switch (syntax->color_conversion_type) {
305*437bfbebSnyanmisaka         case 0 : {  /* BT.601 */
306*437bfbebSnyanmisaka             /*
307*437bfbebSnyanmisaka              * Y  = 0.2989 R + 0.5866 G + 0.1145 B
308*437bfbebSnyanmisaka              * Cb = 0.5647 (B - Y) + 128
309*437bfbebSnyanmisaka              * Cr = 0.7132 (R - Y) + 128
310*437bfbebSnyanmisaka              */
311*437bfbebSnyanmisaka             coeffA = 19589;
312*437bfbebSnyanmisaka             coeffB = 38443;
313*437bfbebSnyanmisaka             coeffC = 7504;
314*437bfbebSnyanmisaka             coeffE = 37008;
315*437bfbebSnyanmisaka             coeffF = 46740;
316*437bfbebSnyanmisaka         } break;
317*437bfbebSnyanmisaka         case 1 : {  /* BT.709 */
318*437bfbebSnyanmisaka             /*
319*437bfbebSnyanmisaka              * Y  = 0.2126 R + 0.7152 G + 0.0722 B
320*437bfbebSnyanmisaka              * Cb = 0.5389 (B - Y) + 128
321*437bfbebSnyanmisaka              * Cr = 0.6350 (R - Y) + 128
322*437bfbebSnyanmisaka              */
323*437bfbebSnyanmisaka             coeffA = 13933;
324*437bfbebSnyanmisaka             coeffB = 46871;
325*437bfbebSnyanmisaka             coeffC = 4732;
326*437bfbebSnyanmisaka             coeffE = 35317;
327*437bfbebSnyanmisaka             coeffF = 41615;
328*437bfbebSnyanmisaka         } break;
329*437bfbebSnyanmisaka         case 2 : {
330*437bfbebSnyanmisaka             coeffA = syntax->coeffA;
331*437bfbebSnyanmisaka             coeffB = syntax->coeffB;
332*437bfbebSnyanmisaka             coeffC = syntax->coeffC;
333*437bfbebSnyanmisaka             coeffE = syntax->coeffE;
334*437bfbebSnyanmisaka             coeffF = syntax->coeffF;
335*437bfbebSnyanmisaka         } break;
336*437bfbebSnyanmisaka         default : {
337*437bfbebSnyanmisaka             mpp_err("invalid color conversion type %d\n",
338*437bfbebSnyanmisaka                     syntax->color_conversion_type);
339*437bfbebSnyanmisaka             coeffA = 19589;
340*437bfbebSnyanmisaka             coeffB = 38443;
341*437bfbebSnyanmisaka             coeffC = 7504;
342*437bfbebSnyanmisaka             coeffE = 37008;
343*437bfbebSnyanmisaka             coeffF = 46740;
344*437bfbebSnyanmisaka         } break;
345*437bfbebSnyanmisaka         }
346*437bfbebSnyanmisaka 
347*437bfbebSnyanmisaka         regs[53] = coeffA | (coeffB << 16);
348*437bfbebSnyanmisaka         regs[54] = coeffC | (coeffE << 16);
349*437bfbebSnyanmisaka         regs[55] = ((fmt_cfg.b_mask & 0x1f) << 26) |
350*437bfbebSnyanmisaka                    ((fmt_cfg.g_mask & 0x1f) << 21) |
351*437bfbebSnyanmisaka                    ((fmt_cfg.r_mask & 0x1f) << 16) | coeffF;
352*437bfbebSnyanmisaka     }
353*437bfbebSnyanmisaka 
354*437bfbebSnyanmisaka     regs[20] = ((syntax->part_rows & 0xff) << 16) | jpege_restart_marker[0];
355*437bfbebSnyanmisaka 
356*437bfbebSnyanmisaka     regs[14] |= 0x001;
357*437bfbebSnyanmisaka 
358*437bfbebSnyanmisaka     {
359*437bfbebSnyanmisaka         RK_S32 i;
360*437bfbebSnyanmisaka 
361*437bfbebSnyanmisaka         for (i = 0; i < 16; i++) {
362*437bfbebSnyanmisaka             /* qtable need to reorder in particular order */
363*437bfbebSnyanmisaka             regs[i + 64] = ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 0]] << 24 |
364*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 1]] << 16 |
365*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 2]] << 8 |
366*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 3]];
367*437bfbebSnyanmisaka         }
368*437bfbebSnyanmisaka         for (i = 0; i < 16; i++) {
369*437bfbebSnyanmisaka             /* qtable need to reorder in particular order */
370*437bfbebSnyanmisaka             regs[i + 80] = ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 0]] << 24 |
371*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 1]] << 16 |
372*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 2]] << 8 |
373*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 3]];
374*437bfbebSnyanmisaka         }
375*437bfbebSnyanmisaka     }
376*437bfbebSnyanmisaka 
377*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
378*437bfbebSnyanmisaka     return MPP_OK;
379*437bfbebSnyanmisaka }
380*437bfbebSnyanmisaka 
hal_jpege_vepu1_start(void * hal,HalEncTask * task)381*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_start(void *hal, HalEncTask *task)
382*437bfbebSnyanmisaka {
383*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
384*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
385*437bfbebSnyanmisaka 
386*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
387*437bfbebSnyanmisaka 
388*437bfbebSnyanmisaka     hal_jpege_vepu1_set_extra_info(ctx->dev, &ctx->syntax, 0);
389*437bfbebSnyanmisaka 
390*437bfbebSnyanmisaka     do {
391*437bfbebSnyanmisaka         MppDevRegWrCfg wr_cfg;
392*437bfbebSnyanmisaka         MppDevRegRdCfg rd_cfg;
393*437bfbebSnyanmisaka         RK_U32 reg_size = ctx->reg_size;
394*437bfbebSnyanmisaka 
395*437bfbebSnyanmisaka         wr_cfg.reg = ctx->regs;
396*437bfbebSnyanmisaka         wr_cfg.size = reg_size;
397*437bfbebSnyanmisaka         wr_cfg.offset = 0;
398*437bfbebSnyanmisaka 
399*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
400*437bfbebSnyanmisaka         if (ret) {
401*437bfbebSnyanmisaka             mpp_err_f("set register write failed %d\n", ret);
402*437bfbebSnyanmisaka             break;
403*437bfbebSnyanmisaka         }
404*437bfbebSnyanmisaka 
405*437bfbebSnyanmisaka         rd_cfg.reg = ctx->regs;
406*437bfbebSnyanmisaka         rd_cfg.size = reg_size;
407*437bfbebSnyanmisaka         rd_cfg.offset = 0;
408*437bfbebSnyanmisaka 
409*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
410*437bfbebSnyanmisaka         if (ret) {
411*437bfbebSnyanmisaka             mpp_err_f("set register read failed %d\n", ret);
412*437bfbebSnyanmisaka             break;
413*437bfbebSnyanmisaka         }
414*437bfbebSnyanmisaka 
415*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
416*437bfbebSnyanmisaka         if (ret) {
417*437bfbebSnyanmisaka             mpp_err_f("send cmd failed %d\n", ret);
418*437bfbebSnyanmisaka             break;
419*437bfbebSnyanmisaka         }
420*437bfbebSnyanmisaka     } while (0);
421*437bfbebSnyanmisaka 
422*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
423*437bfbebSnyanmisaka     (void)task;
424*437bfbebSnyanmisaka     return ret;
425*437bfbebSnyanmisaka }
426*437bfbebSnyanmisaka 
hal_jpege_vepu1_wait(void * hal,HalEncTask * task)427*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_wait(void *hal, HalEncTask *task)
428*437bfbebSnyanmisaka {
429*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
430*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
431*437bfbebSnyanmisaka     JpegeBits bits = ctx->bits;
432*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)ctx->regs;
433*437bfbebSnyanmisaka     JpegeFeedback *feedback = &ctx->feedback;
434*437bfbebSnyanmisaka     RK_U32 val;
435*437bfbebSnyanmisaka     RK_U32 sw_bit = 0;
436*437bfbebSnyanmisaka     RK_U32 hw_bit = 0;
437*437bfbebSnyanmisaka 
438*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
439*437bfbebSnyanmisaka 
440*437bfbebSnyanmisaka     if (ctx->dev) {
441*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
442*437bfbebSnyanmisaka         if (ret)
443*437bfbebSnyanmisaka             mpp_err_f("poll cmd failed %d\n", ret);
444*437bfbebSnyanmisaka     }
445*437bfbebSnyanmisaka 
446*437bfbebSnyanmisaka     val = regs[1];
447*437bfbebSnyanmisaka     hal_jpege_dbg_output("hw_status %08x\n", val);
448*437bfbebSnyanmisaka     feedback->hw_status = val & 0x70;
449*437bfbebSnyanmisaka     val = regs[24];
450*437bfbebSnyanmisaka 
451*437bfbebSnyanmisaka     sw_bit = jpege_bits_get_bitpos(bits);
452*437bfbebSnyanmisaka     hw_bit = val;
453*437bfbebSnyanmisaka 
454*437bfbebSnyanmisaka     // NOTE: hardware will return 64 bit access byte count
455*437bfbebSnyanmisaka     feedback->stream_length = ((sw_bit / 8) & (~0x7)) + hw_bit / 8;
456*437bfbebSnyanmisaka     task->length = feedback->stream_length;
457*437bfbebSnyanmisaka     task->hw_length = task->length - ctx->hal_start_pos;
458*437bfbebSnyanmisaka     hal_jpege_dbg_output("stream bit: sw %d hw %d total %d hw_length %d\n",
459*437bfbebSnyanmisaka                          sw_bit, hw_bit, feedback->stream_length, task->hw_length);
460*437bfbebSnyanmisaka 
461*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
462*437bfbebSnyanmisaka     return ret;
463*437bfbebSnyanmisaka }
464*437bfbebSnyanmisaka 
hal_jpege_vepu1_part_start(void * hal,HalEncTask * task)465*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_part_start(void *hal, HalEncTask *task)
466*437bfbebSnyanmisaka {
467*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
468*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
469*437bfbebSnyanmisaka     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
470*437bfbebSnyanmisaka     RK_U32 mcu_w = syntax->mcu_hor_cnt;
471*437bfbebSnyanmisaka     RK_U32 mcu_h = syntax->mcu_ver_cnt;
472*437bfbebSnyanmisaka     RK_U32 mcu_y = ctx->mcu_y;
473*437bfbebSnyanmisaka     RK_U32 part_mcu_h = syntax->part_rows;
474*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)ctx->regs;
475*437bfbebSnyanmisaka     RK_U32 part_enc_h;
476*437bfbebSnyanmisaka     RK_U32 part_enc_mcu_h;
477*437bfbebSnyanmisaka     RK_U32 part_y_fill;
478*437bfbebSnyanmisaka     RK_U32 part_not_end;
479*437bfbebSnyanmisaka 
480*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter part start %p\n", hal);
481*437bfbebSnyanmisaka 
482*437bfbebSnyanmisaka     /* Fix register for each part encoding */
483*437bfbebSnyanmisaka     task->part_first = !mcu_y;
484*437bfbebSnyanmisaka     if (mcu_y + part_mcu_h < mcu_h) {
485*437bfbebSnyanmisaka         part_enc_h = part_mcu_h * 16;
486*437bfbebSnyanmisaka         part_enc_mcu_h = part_mcu_h;
487*437bfbebSnyanmisaka         part_y_fill = 0;
488*437bfbebSnyanmisaka         part_not_end = 1;
489*437bfbebSnyanmisaka         task->part_last = 0;
490*437bfbebSnyanmisaka     } else {
491*437bfbebSnyanmisaka         part_enc_h = syntax->height - mcu_y * 16;
492*437bfbebSnyanmisaka         part_enc_mcu_h = MPP_ALIGN(part_enc_h, 16) / 16;;
493*437bfbebSnyanmisaka         part_y_fill = ctx->part_y_fill;
494*437bfbebSnyanmisaka         part_not_end = 0;
495*437bfbebSnyanmisaka         task->part_last = 1;
496*437bfbebSnyanmisaka     }
497*437bfbebSnyanmisaka 
498*437bfbebSnyanmisaka     hal_jpege_dbg_detail("part first %d last %d\n", task->part_first, task->part_last);
499*437bfbebSnyanmisaka 
500*437bfbebSnyanmisaka     get_msb_lsb_at_pos(&regs[22], &regs[23], ctx->base, ctx->part_bytepos);
501*437bfbebSnyanmisaka 
502*437bfbebSnyanmisaka     regs[24] = ctx->size - ctx->part_bytepos;
503*437bfbebSnyanmisaka 
504*437bfbebSnyanmisaka     regs[15] = (regs[15] & 0xfffffc3f) | (part_y_fill << 6);
505*437bfbebSnyanmisaka 
506*437bfbebSnyanmisaka     regs[37] = ((ctx->part_bytepos & 7) * 8) << 23;
507*437bfbebSnyanmisaka 
508*437bfbebSnyanmisaka     regs[5] = mpp_buffer_get_fd(task->output);
509*437bfbebSnyanmisaka     if (ctx->part_bytepos)
510*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(ctx->dev, 5, ctx->part_bytepos);
511*437bfbebSnyanmisaka 
512*437bfbebSnyanmisaka     regs[14] = (1 << 31) |
513*437bfbebSnyanmisaka                (0 << 30) |
514*437bfbebSnyanmisaka                (0 << 29) |
515*437bfbebSnyanmisaka                (mcu_w << 19) |
516*437bfbebSnyanmisaka                (part_enc_mcu_h << 10) |
517*437bfbebSnyanmisaka                (1 << 3) | (2 << 1) | 1;
518*437bfbebSnyanmisaka 
519*437bfbebSnyanmisaka     regs[20] = part_not_end << 24 | jpege_restart_marker[ctx->rst_marker_idx & 7];
520*437bfbebSnyanmisaka     ctx->rst_marker_idx++;
521*437bfbebSnyanmisaka 
522*437bfbebSnyanmisaka     hal_jpege_vepu1_set_extra_info(ctx->dev, syntax, mcu_y);
523*437bfbebSnyanmisaka     ctx->mcu_y += part_enc_mcu_h;
524*437bfbebSnyanmisaka 
525*437bfbebSnyanmisaka     do {
526*437bfbebSnyanmisaka         MppDevRegWrCfg wr_cfg;
527*437bfbebSnyanmisaka         MppDevRegRdCfg rd_cfg;
528*437bfbebSnyanmisaka         RK_U32 reg_size = ctx->reg_size;
529*437bfbebSnyanmisaka 
530*437bfbebSnyanmisaka         wr_cfg.reg = ctx->regs;
531*437bfbebSnyanmisaka         wr_cfg.size = reg_size;
532*437bfbebSnyanmisaka         wr_cfg.offset = 0;
533*437bfbebSnyanmisaka 
534*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
535*437bfbebSnyanmisaka         if (ret) {
536*437bfbebSnyanmisaka             mpp_err_f("set register write failed %d\n", ret);
537*437bfbebSnyanmisaka             break;
538*437bfbebSnyanmisaka         }
539*437bfbebSnyanmisaka 
540*437bfbebSnyanmisaka         rd_cfg.reg = ctx->regs_out;
541*437bfbebSnyanmisaka         rd_cfg.size = reg_size;
542*437bfbebSnyanmisaka         rd_cfg.offset = 0;
543*437bfbebSnyanmisaka 
544*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
545*437bfbebSnyanmisaka         if (ret) {
546*437bfbebSnyanmisaka             mpp_err_f("set register read failed %d\n", ret);
547*437bfbebSnyanmisaka             break;
548*437bfbebSnyanmisaka         }
549*437bfbebSnyanmisaka 
550*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
551*437bfbebSnyanmisaka         if (ret) {
552*437bfbebSnyanmisaka             mpp_err_f("send cmd failed %d\n", ret);
553*437bfbebSnyanmisaka             break;
554*437bfbebSnyanmisaka         }
555*437bfbebSnyanmisaka     } while (0);
556*437bfbebSnyanmisaka 
557*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave part start %p\n", hal);
558*437bfbebSnyanmisaka     (void)task;
559*437bfbebSnyanmisaka     return ret;
560*437bfbebSnyanmisaka }
561*437bfbebSnyanmisaka 
hal_jpege_vepu1_part_wait(void * hal,HalEncTask * task)562*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_part_wait(void *hal, HalEncTask *task)
563*437bfbebSnyanmisaka {
564*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
565*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
566*437bfbebSnyanmisaka     RK_U32 *regs = ctx->regs_out;
567*437bfbebSnyanmisaka     JpegeFeedback *feedback = &ctx->feedback;
568*437bfbebSnyanmisaka     RK_U32 hw_bit = 0;
569*437bfbebSnyanmisaka 
570*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter part wait %p\n", hal);
571*437bfbebSnyanmisaka 
572*437bfbebSnyanmisaka     if (ctx->dev) {
573*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
574*437bfbebSnyanmisaka         if (ret)
575*437bfbebSnyanmisaka             mpp_err_f("poll cmd failed %d\n", ret);
576*437bfbebSnyanmisaka     }
577*437bfbebSnyanmisaka 
578*437bfbebSnyanmisaka     hal_jpege_dbg_detail("hw_status %08x\n", regs[1]);
579*437bfbebSnyanmisaka 
580*437bfbebSnyanmisaka     hw_bit = regs[24];
581*437bfbebSnyanmisaka 
582*437bfbebSnyanmisaka     hal_jpege_dbg_detail("byte pos %d -> %d\n", ctx->part_bytepos,
583*437bfbebSnyanmisaka                          (ctx->part_bytepos & (~7)) + (hw_bit / 8));
584*437bfbebSnyanmisaka     ctx->part_bytepos = (ctx->part_bytepos & (~7)) + (hw_bit / 8);
585*437bfbebSnyanmisaka 
586*437bfbebSnyanmisaka     feedback->stream_length = ctx->part_bytepos;
587*437bfbebSnyanmisaka     task->length = ctx->part_bytepos;
588*437bfbebSnyanmisaka     task->hw_length = task->length - ctx->hal_start_pos;
589*437bfbebSnyanmisaka 
590*437bfbebSnyanmisaka     hal_jpege_dbg_detail("stream_length %d, hw_byte %d",
591*437bfbebSnyanmisaka                          feedback->stream_length, hw_bit / 8);
592*437bfbebSnyanmisaka 
593*437bfbebSnyanmisaka     hal_jpege_dbg_output("stream bit: sw %d hw %d total %d hw_length %d\n",
594*437bfbebSnyanmisaka                          ctx->sw_bit, hw_bit, feedback->stream_length, task->hw_length);
595*437bfbebSnyanmisaka 
596*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave part wait %p\n", hal);
597*437bfbebSnyanmisaka     return ret;
598*437bfbebSnyanmisaka }
599*437bfbebSnyanmisaka 
hal_jpege_vepu1_ret_task(void * hal,HalEncTask * task)600*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu1_ret_task(void *hal, HalEncTask *task)
601*437bfbebSnyanmisaka {
602*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
603*437bfbebSnyanmisaka 
604*437bfbebSnyanmisaka     task->rc_task->info.bit_real = ctx->feedback.stream_length * 8;
605*437bfbebSnyanmisaka     task->hal_ret.data = &ctx->feedback;
606*437bfbebSnyanmisaka     task->hal_ret.number = 1;
607*437bfbebSnyanmisaka     task->rc_task->info.quality_real = task->rc_task->info.quality_target;
608*437bfbebSnyanmisaka 
609*437bfbebSnyanmisaka     return MPP_OK;
610*437bfbebSnyanmisaka }
611*437bfbebSnyanmisaka 
612*437bfbebSnyanmisaka const MppEncHalApi hal_jpege_vepu1 = {
613*437bfbebSnyanmisaka     .name       = "hal_jpege_vepu1",
614*437bfbebSnyanmisaka     .coding     = MPP_VIDEO_CodingMJPEG,
615*437bfbebSnyanmisaka     .ctx_size   = sizeof(HalJpegeCtx),
616*437bfbebSnyanmisaka     .flag       = 0,
617*437bfbebSnyanmisaka     .init       = hal_jpege_vepu1_init,
618*437bfbebSnyanmisaka     .deinit     = hal_jpege_vepu1_deinit,
619*437bfbebSnyanmisaka     .prepare    = NULL,
620*437bfbebSnyanmisaka     .get_task   = hal_jpege_vepu1_get_task,
621*437bfbebSnyanmisaka     .gen_regs   = hal_jpege_vepu1_gen_regs,
622*437bfbebSnyanmisaka     .start      = hal_jpege_vepu1_start,
623*437bfbebSnyanmisaka     .wait       = hal_jpege_vepu1_wait,
624*437bfbebSnyanmisaka     .part_start = hal_jpege_vepu1_part_start,
625*437bfbebSnyanmisaka     .part_wait  = hal_jpege_vepu1_part_wait,
626*437bfbebSnyanmisaka     .ret_task   = hal_jpege_vepu1_ret_task,
627*437bfbebSnyanmisaka };
628