xref: /rockchip-linux_mpp/mpp/hal/vpu/jpege/hal_jpege_vepu2_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_vepu2"
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 #include "mpp_dmabuf.h"
26*437bfbebSnyanmisaka 
27*437bfbebSnyanmisaka #include "mpp_enc_hal.h"
28*437bfbebSnyanmisaka #include "vcodec_service.h"
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka #include "hal_jpege_debug.h"
31*437bfbebSnyanmisaka #include "hal_jpege_api_v2.h"
32*437bfbebSnyanmisaka #include "hal_jpege_base.h"
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka #define VEPU_JPEGE_VEPU2_NUM_REGS   184
35*437bfbebSnyanmisaka #define VEPU2_REG_INPUT_Y           48
36*437bfbebSnyanmisaka #define VEPU2_REG_INPUT_U           49
37*437bfbebSnyanmisaka #define VEPU2_REG_INPUT_V           50
38*437bfbebSnyanmisaka 
39*437bfbebSnyanmisaka typedef struct jpege_vepu2_reg_set_t {
40*437bfbebSnyanmisaka     RK_U32  val[VEPU_JPEGE_VEPU2_NUM_REGS];
41*437bfbebSnyanmisaka } jpege_vepu2_reg_set;
42*437bfbebSnyanmisaka 
43*437bfbebSnyanmisaka #define MAX_CORE_NUM                4
44*437bfbebSnyanmisaka 
45*437bfbebSnyanmisaka typedef struct JpegeMultiCoreCtx_t {
46*437bfbebSnyanmisaka     RK_U32              multi_core_enabled;
47*437bfbebSnyanmisaka     RK_U32              partion_num;
48*437bfbebSnyanmisaka     MppDevRegOffCfgs    *reg_cfg;
49*437bfbebSnyanmisaka 
50*437bfbebSnyanmisaka     MppBufferGroup      partions_group;
51*437bfbebSnyanmisaka     MppBuffer           partions_buf[MAX_CORE_NUM - 1];
52*437bfbebSnyanmisaka     RK_U32              buf_size;
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka     RK_U32              part_rows[MAX_CORE_NUM];
55*437bfbebSnyanmisaka     RK_U32              ecs_cnt[MAX_CORE_NUM];
56*437bfbebSnyanmisaka 
57*437bfbebSnyanmisaka     void                *regs_base;
58*437bfbebSnyanmisaka     void                *regs[MAX_CORE_NUM];
59*437bfbebSnyanmisaka     void                *regs_out[MAX_CORE_NUM];
60*437bfbebSnyanmisaka } JpegeMultiCoreCtx;
61*437bfbebSnyanmisaka 
hal_jpege_vepu2_init(void * hal,MppEncHalCfg * cfg)62*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_init(void *hal, MppEncHalCfg *cfg)
63*437bfbebSnyanmisaka {
64*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
65*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
66*437bfbebSnyanmisaka     MppClientType type;
67*437bfbebSnyanmisaka     RK_U32 vcodec_type = mpp_get_vcodec_type();
68*437bfbebSnyanmisaka 
69*437bfbebSnyanmisaka     mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
70*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p cfg %p\n", hal, cfg);
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka     /* update output to MppEnc */
73*437bfbebSnyanmisaka     type = (vcodec_type & HAVE_VEPU2_JPEG) ?
74*437bfbebSnyanmisaka            VPU_CLIENT_VEPU2_JPEG : VPU_CLIENT_VEPU2;
75*437bfbebSnyanmisaka 
76*437bfbebSnyanmisaka     cfg->type = type;
77*437bfbebSnyanmisaka     ret = mpp_dev_init(&cfg->dev, type);
78*437bfbebSnyanmisaka     if (ret) {
79*437bfbebSnyanmisaka         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
80*437bfbebSnyanmisaka         return ret;
81*437bfbebSnyanmisaka     }
82*437bfbebSnyanmisaka     ctx->dev = cfg->dev;
83*437bfbebSnyanmisaka     ctx->type = cfg->type;
84*437bfbebSnyanmisaka     ctx->task_cnt = cfg->task_cnt;
85*437bfbebSnyanmisaka 
86*437bfbebSnyanmisaka     jpege_bits_init(&ctx->bits);
87*437bfbebSnyanmisaka     mpp_assert(ctx->bits);
88*437bfbebSnyanmisaka 
89*437bfbebSnyanmisaka     ctx->cfg = cfg->cfg;
90*437bfbebSnyanmisaka     ctx->reg_size = sizeof(RK_U32) * VEPU_JPEGE_VEPU2_NUM_REGS;
91*437bfbebSnyanmisaka     ctx->regs = mpp_calloc_size(void, (ctx->reg_size + EXTRA_INFO_SIZE) * ctx->task_cnt);
92*437bfbebSnyanmisaka     if (NULL == ctx->regs) {
93*437bfbebSnyanmisaka         mpp_err_f("failed to malloc vepu2 regs\n");
94*437bfbebSnyanmisaka         return MPP_NOK;
95*437bfbebSnyanmisaka     }
96*437bfbebSnyanmisaka 
97*437bfbebSnyanmisaka     ctx->regs_out = mpp_calloc_size(void, (ctx->reg_size + EXTRA_INFO_SIZE) *  ctx->task_cnt);
98*437bfbebSnyanmisaka     if (NULL == ctx->regs_out) {
99*437bfbebSnyanmisaka         mpp_err_f("failed to malloc vepu2 regs\n");
100*437bfbebSnyanmisaka         return MPP_NOK;
101*437bfbebSnyanmisaka     }
102*437bfbebSnyanmisaka 
103*437bfbebSnyanmisaka     hal_jpege_rc_init(&ctx->hal_rc);
104*437bfbebSnyanmisaka 
105*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
106*437bfbebSnyanmisaka     return MPP_OK;
107*437bfbebSnyanmisaka }
108*437bfbebSnyanmisaka 
hal_jpege_vepu2_deinit(void * hal)109*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_deinit(void *hal)
110*437bfbebSnyanmisaka {
111*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
112*437bfbebSnyanmisaka 
113*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
114*437bfbebSnyanmisaka 
115*437bfbebSnyanmisaka     if (ctx->bits) {
116*437bfbebSnyanmisaka         jpege_bits_deinit(ctx->bits);
117*437bfbebSnyanmisaka         ctx->bits = NULL;
118*437bfbebSnyanmisaka     }
119*437bfbebSnyanmisaka 
120*437bfbebSnyanmisaka     if (ctx->dev) {
121*437bfbebSnyanmisaka         mpp_dev_deinit(ctx->dev);
122*437bfbebSnyanmisaka         ctx->dev = NULL;
123*437bfbebSnyanmisaka     }
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka     if (ctx->ctx_ext) {
126*437bfbebSnyanmisaka         JpegeMultiCoreCtx *ctx_ext = ctx->ctx_ext;
127*437bfbebSnyanmisaka         RK_U32 i;
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka         if (ctx_ext->reg_cfg) {
130*437bfbebSnyanmisaka             mpp_dev_multi_offset_deinit(ctx_ext->reg_cfg);
131*437bfbebSnyanmisaka             ctx_ext->reg_cfg = NULL;
132*437bfbebSnyanmisaka         }
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka         for (i = 0; i < MAX_CORE_NUM - 1; i++)
135*437bfbebSnyanmisaka             if (ctx_ext->partions_buf[i])
136*437bfbebSnyanmisaka                 mpp_buffer_put(ctx_ext->partions_buf[i]);
137*437bfbebSnyanmisaka 
138*437bfbebSnyanmisaka         if (ctx_ext->partions_group) {
139*437bfbebSnyanmisaka             mpp_buffer_group_put(ctx_ext->partions_group);
140*437bfbebSnyanmisaka             ctx_ext->partions_group = NULL;
141*437bfbebSnyanmisaka         }
142*437bfbebSnyanmisaka 
143*437bfbebSnyanmisaka         MPP_FREE(ctx_ext->regs_base);
144*437bfbebSnyanmisaka         MPP_FREE(ctx->ctx_ext);
145*437bfbebSnyanmisaka     }
146*437bfbebSnyanmisaka 
147*437bfbebSnyanmisaka     MPP_FREE(ctx->regs);
148*437bfbebSnyanmisaka     MPP_FREE(ctx->regs_out);
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
151*437bfbebSnyanmisaka     return MPP_OK;
152*437bfbebSnyanmisaka }
153*437bfbebSnyanmisaka 
hal_jpege_vepu2_get_task(void * hal,HalEncTask * task)154*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_get_task(void *hal, HalEncTask *task)
155*437bfbebSnyanmisaka {
156*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
157*437bfbebSnyanmisaka     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
158*437bfbebSnyanmisaka     JpegeMultiCoreCtx *ctx_ext = (JpegeMultiCoreCtx *)ctx->ctx_ext;
159*437bfbebSnyanmisaka     RK_U32 i = 0;
160*437bfbebSnyanmisaka 
161*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
162*437bfbebSnyanmisaka 
163*437bfbebSnyanmisaka     memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka     ctx->hal_start_pos = mpp_packet_get_length(task->packet);
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka     /* prepare for part encoding */
168*437bfbebSnyanmisaka     ctx->mcu_y = 0;
169*437bfbebSnyanmisaka     ctx->mcu_h = syntax->mcu_ver_cnt;
170*437bfbebSnyanmisaka     ctx->sw_bit = 0;
171*437bfbebSnyanmisaka     ctx->part_bytepos = 0;
172*437bfbebSnyanmisaka     ctx->part_x_fill = 0;
173*437bfbebSnyanmisaka     ctx->part_y_fill = 0;
174*437bfbebSnyanmisaka     ctx->rst_marker_idx = 0;
175*437bfbebSnyanmisaka     task->part_first = 1;
176*437bfbebSnyanmisaka     task->part_last = 0;
177*437bfbebSnyanmisaka     task->flags.reg_idx = 0;
178*437bfbebSnyanmisaka 
179*437bfbebSnyanmisaka     /* rk3588 4 core frame parallel */
180*437bfbebSnyanmisaka     if (ctx->task_cnt > 1) {
181*437bfbebSnyanmisaka         task->flags.reg_idx = ctx->task_idx++;
182*437bfbebSnyanmisaka         if (ctx->task_idx >= ctx->task_cnt)
183*437bfbebSnyanmisaka             ctx->task_idx = 0;
184*437bfbebSnyanmisaka         goto MULTI_CORE_SPLIT_DONE;
185*437bfbebSnyanmisaka     }
186*437bfbebSnyanmisaka 
187*437bfbebSnyanmisaka     /* Split single task to multi cores on rk3588 */
188*437bfbebSnyanmisaka     if (ctx_ext)
189*437bfbebSnyanmisaka         ctx_ext->multi_core_enabled = 0;
190*437bfbebSnyanmisaka 
191*437bfbebSnyanmisaka     if (ctx->type == VPU_CLIENT_VEPU2_JPEG) {
192*437bfbebSnyanmisaka         RK_U32 width = ctx->cfg->prep.width;
193*437bfbebSnyanmisaka         RK_U32 height = ctx->cfg->prep.height;
194*437bfbebSnyanmisaka         RK_U32 buf_size = width * height / 2;
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka         /* small image do not need to split into four segments */
197*437bfbebSnyanmisaka         if (width * height <= 1280 * 720 && (height <= 720 || width <= 720))
198*437bfbebSnyanmisaka             goto MULTI_CORE_SPLIT_DONE;
199*437bfbebSnyanmisaka 
200*437bfbebSnyanmisaka         if (!ctx_ext) {
201*437bfbebSnyanmisaka             ctx_ext = mpp_calloc(JpegeMultiCoreCtx, 1);
202*437bfbebSnyanmisaka             ctx->ctx_ext = ctx_ext;
203*437bfbebSnyanmisaka         }
204*437bfbebSnyanmisaka 
205*437bfbebSnyanmisaka         mpp_assert(ctx_ext);
206*437bfbebSnyanmisaka 
207*437bfbebSnyanmisaka         if (!ctx_ext->partions_group) {
208*437bfbebSnyanmisaka             mpp_buffer_group_get_internal(&ctx_ext->partions_group, MPP_BUFFER_TYPE_DMA_HEAP | MPP_BUFFER_FLAGS_CACHABLE);
209*437bfbebSnyanmisaka             if (!ctx_ext->partions_group)
210*437bfbebSnyanmisaka                 mpp_buffer_group_get_internal(&ctx_ext->partions_group, MPP_BUFFER_TYPE_ION);
211*437bfbebSnyanmisaka         }
212*437bfbebSnyanmisaka 
213*437bfbebSnyanmisaka         mpp_assert(ctx_ext->partions_group);
214*437bfbebSnyanmisaka 
215*437bfbebSnyanmisaka         if (ctx_ext->buf_size != buf_size) {
216*437bfbebSnyanmisaka             MppBuffer buf = NULL;
217*437bfbebSnyanmisaka 
218*437bfbebSnyanmisaka             for (i = 0; i < MAX_CORE_NUM - 1; i++) {
219*437bfbebSnyanmisaka                 buf = ctx_ext->partions_buf[i];
220*437bfbebSnyanmisaka                 if (buf)
221*437bfbebSnyanmisaka                     mpp_buffer_put(buf);
222*437bfbebSnyanmisaka             }
223*437bfbebSnyanmisaka 
224*437bfbebSnyanmisaka             mpp_buffer_group_clear(ctx_ext->partions_group);
225*437bfbebSnyanmisaka 
226*437bfbebSnyanmisaka             for (i = 0; i < MAX_CORE_NUM - 1; i++) {
227*437bfbebSnyanmisaka                 mpp_buffer_get(ctx_ext->partions_group, &buf, buf_size);
228*437bfbebSnyanmisaka                 mpp_assert(buf);
229*437bfbebSnyanmisaka                 ctx_ext->partions_buf[i] = buf;
230*437bfbebSnyanmisaka             }
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka             ctx_ext->buf_size = buf_size;
233*437bfbebSnyanmisaka         }
234*437bfbebSnyanmisaka 
235*437bfbebSnyanmisaka         if (!ctx_ext->regs_base) {
236*437bfbebSnyanmisaka             void *regs_base = mpp_calloc_size(void, ctx->reg_size * MAX_CORE_NUM * 2);
237*437bfbebSnyanmisaka             size_t reg_size = ctx->reg_size;
238*437bfbebSnyanmisaka 
239*437bfbebSnyanmisaka             ctx_ext->regs_base = regs_base;
240*437bfbebSnyanmisaka             for (i = 0; i < MAX_CORE_NUM; i++) {
241*437bfbebSnyanmisaka                 ctx_ext->regs[i] = regs_base;
242*437bfbebSnyanmisaka                 regs_base += reg_size;
243*437bfbebSnyanmisaka 
244*437bfbebSnyanmisaka                 ctx_ext->regs_out[i] = regs_base;
245*437bfbebSnyanmisaka                 regs_base += reg_size;
246*437bfbebSnyanmisaka             }
247*437bfbebSnyanmisaka         }
248*437bfbebSnyanmisaka 
249*437bfbebSnyanmisaka         {
250*437bfbebSnyanmisaka             RK_U32 mb_w = MPP_ALIGN(width, 16) / 16;
251*437bfbebSnyanmisaka             RK_U32 mb_h = MPP_ALIGN(height, 16) / 16;
252*437bfbebSnyanmisaka             RK_U32 part_rows = MPP_ALIGN(mb_h, 4) / 4;
253*437bfbebSnyanmisaka 
254*437bfbebSnyanmisaka             ctx_ext->partion_num = 0;
255*437bfbebSnyanmisaka 
256*437bfbebSnyanmisaka             if (ctx->cfg->split.split_mode == MPP_ENC_SPLIT_BY_CTU) {
257*437bfbebSnyanmisaka                 RK_U32 ecs_num = (mb_h + syntax->part_rows - 1) / syntax->part_rows;
258*437bfbebSnyanmisaka                 RK_U32 *core_ecs = ctx_ext->ecs_cnt;
259*437bfbebSnyanmisaka 
260*437bfbebSnyanmisaka                 if (ecs_num > 24 || ecs_num <= 8) {
261*437bfbebSnyanmisaka                     RK_U32 divider = ecs_num > 24 ? 8 : 1;
262*437bfbebSnyanmisaka                     RK_U32 quotient = ecs_num / divider;
263*437bfbebSnyanmisaka                     RK_U32 remainder = ecs_num % divider;
264*437bfbebSnyanmisaka                     RK_U32 runs = quotient  / MAX_CORE_NUM;
265*437bfbebSnyanmisaka                     RK_U32 runs_left = quotient % MAX_CORE_NUM;
266*437bfbebSnyanmisaka 
267*437bfbebSnyanmisaka                     if (runs > 0) {
268*437bfbebSnyanmisaka                         for (i = 0; i < MAX_CORE_NUM; i++)
269*437bfbebSnyanmisaka                             core_ecs[i] = runs * divider;
270*437bfbebSnyanmisaka                     }
271*437bfbebSnyanmisaka 
272*437bfbebSnyanmisaka                     for (i = 0; i < runs_left; i++)
273*437bfbebSnyanmisaka                         core_ecs[i] += divider;
274*437bfbebSnyanmisaka 
275*437bfbebSnyanmisaka                     core_ecs[MAX_CORE_NUM - 1] += remainder;
276*437bfbebSnyanmisaka                 } else if (ecs_num > 20) {
277*437bfbebSnyanmisaka                     core_ecs[0] = core_ecs[1] = 8;
278*437bfbebSnyanmisaka                     core_ecs[2] = (ecs_num - 8 * 2) / 2;
279*437bfbebSnyanmisaka                     core_ecs[3] = ecs_num - 8 * 2 - core_ecs[2];
280*437bfbebSnyanmisaka                 } else if (ecs_num > 16) {
281*437bfbebSnyanmisaka                     core_ecs[0] = 8;
282*437bfbebSnyanmisaka                     core_ecs[1] = core_ecs[2] = 4;
283*437bfbebSnyanmisaka                     core_ecs[3] = ecs_num - 8 - 4 * 2;
284*437bfbebSnyanmisaka                 } else if (ecs_num > 8) {
285*437bfbebSnyanmisaka                     core_ecs[0] = core_ecs[1] = 4;
286*437bfbebSnyanmisaka                     core_ecs[2] = (ecs_num - 4 * 2) / 2;
287*437bfbebSnyanmisaka                     core_ecs[3] = ecs_num - 4 * 2 - core_ecs[2];
288*437bfbebSnyanmisaka                 }
289*437bfbebSnyanmisaka 
290*437bfbebSnyanmisaka                 for (i = 0; i < MAX_CORE_NUM; i++) {
291*437bfbebSnyanmisaka                     ctx_ext->part_rows[i] = core_ecs[i] * syntax->part_rows;
292*437bfbebSnyanmisaka                     hal_jpege_dbg_detail("part %d, ecs %d, rows %d", i, core_ecs[i],
293*437bfbebSnyanmisaka                                          ctx_ext->part_rows[i]);
294*437bfbebSnyanmisaka                     if (core_ecs[i])
295*437bfbebSnyanmisaka                         ctx_ext->partion_num++;
296*437bfbebSnyanmisaka                 }
297*437bfbebSnyanmisaka             } else {
298*437bfbebSnyanmisaka                 for (i = 0; i < MAX_CORE_NUM; i++) {
299*437bfbebSnyanmisaka                     part_rows = (mb_h >= part_rows) ? part_rows : mb_h;
300*437bfbebSnyanmisaka 
301*437bfbebSnyanmisaka                     ctx_ext->part_rows[i] = part_rows;
302*437bfbebSnyanmisaka                     ctx_ext->ecs_cnt[i] = 1;
303*437bfbebSnyanmisaka 
304*437bfbebSnyanmisaka                     hal_jpege_dbg_detail("part %d row %d restart %d\n",
305*437bfbebSnyanmisaka                                          i, part_rows, mb_w * part_rows);
306*437bfbebSnyanmisaka 
307*437bfbebSnyanmisaka                     if (part_rows)
308*437bfbebSnyanmisaka                         ctx_ext->partion_num++;
309*437bfbebSnyanmisaka 
310*437bfbebSnyanmisaka                     if (i == 0 && !ctx->syntax.restart_ri)
311*437bfbebSnyanmisaka                         ctx->syntax.restart_ri = mb_w * part_rows;
312*437bfbebSnyanmisaka 
313*437bfbebSnyanmisaka                     mb_h -= part_rows;
314*437bfbebSnyanmisaka                 }
315*437bfbebSnyanmisaka             }
316*437bfbebSnyanmisaka         }
317*437bfbebSnyanmisaka 
318*437bfbebSnyanmisaka         if (!ctx_ext->reg_cfg)
319*437bfbebSnyanmisaka             mpp_dev_multi_offset_init(&ctx_ext->reg_cfg, 24);
320*437bfbebSnyanmisaka 
321*437bfbebSnyanmisaka         syntax->low_delay = 1;
322*437bfbebSnyanmisaka         ctx_ext->multi_core_enabled = 1;
323*437bfbebSnyanmisaka     }
324*437bfbebSnyanmisaka 
325*437bfbebSnyanmisaka     if (ctx->cfg->jpeg.update) {
326*437bfbebSnyanmisaka         hal_jpege_rc_update(&ctx->hal_rc, syntax);
327*437bfbebSnyanmisaka         ctx->cfg->jpeg.update = 0;
328*437bfbebSnyanmisaka     }
329*437bfbebSnyanmisaka 
330*437bfbebSnyanmisaka     task->rc_task->frm.is_intra = 1;
331*437bfbebSnyanmisaka 
332*437bfbebSnyanmisaka MULTI_CORE_SPLIT_DONE:
333*437bfbebSnyanmisaka 
334*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
335*437bfbebSnyanmisaka 
336*437bfbebSnyanmisaka     return MPP_OK;
337*437bfbebSnyanmisaka }
338*437bfbebSnyanmisaka 
hal_jpege_vepu2_set_extra_info(MppDev dev,JpegeSyntax * syntax,RK_U32 start_mbrow)339*437bfbebSnyanmisaka static MPP_RET hal_jpege_vepu2_set_extra_info(MppDev dev, JpegeSyntax *syntax,
340*437bfbebSnyanmisaka                                               RK_U32 start_mbrow)
341*437bfbebSnyanmisaka {
342*437bfbebSnyanmisaka     VepuOffsetCfg cfg;
343*437bfbebSnyanmisaka 
344*437bfbebSnyanmisaka     cfg.fmt = syntax->format;
345*437bfbebSnyanmisaka     cfg.width = syntax->width;
346*437bfbebSnyanmisaka     cfg.height = syntax->height;
347*437bfbebSnyanmisaka     cfg.hor_stride = syntax->hor_stride;
348*437bfbebSnyanmisaka     cfg.ver_stride = syntax->ver_stride;
349*437bfbebSnyanmisaka     cfg.offset_x = syntax->offset_x;
350*437bfbebSnyanmisaka     cfg.offset_y = syntax->offset_y + start_mbrow * 16;
351*437bfbebSnyanmisaka 
352*437bfbebSnyanmisaka     get_vepu_offset_cfg(&cfg);
353*437bfbebSnyanmisaka 
354*437bfbebSnyanmisaka     if (cfg.offset_byte[0])
355*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, VEPU2_REG_INPUT_Y, cfg.offset_byte[0]);
356*437bfbebSnyanmisaka 
357*437bfbebSnyanmisaka     if (cfg.offset_byte[1])
358*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, VEPU2_REG_INPUT_U, cfg.offset_byte[1]);
359*437bfbebSnyanmisaka 
360*437bfbebSnyanmisaka     if (cfg.offset_byte[2])
361*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, VEPU2_REG_INPUT_V, cfg.offset_byte[2]);
362*437bfbebSnyanmisaka 
363*437bfbebSnyanmisaka     return MPP_OK;
364*437bfbebSnyanmisaka }
365*437bfbebSnyanmisaka 
hal_jpege_vepu2_gen_regs(void * hal,HalEncTask * task)366*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_gen_regs(void *hal, HalEncTask *task)
367*437bfbebSnyanmisaka {
368*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
369*437bfbebSnyanmisaka     MppBuffer input  = task->input;
370*437bfbebSnyanmisaka     MppBuffer output = task->output;
371*437bfbebSnyanmisaka     JpegeSyntax *syntax = &ctx->syntax;
372*437bfbebSnyanmisaka     RK_U32 width        = syntax->width;
373*437bfbebSnyanmisaka     RK_U32 width_align  = MPP_ALIGN(width, 16);
374*437bfbebSnyanmisaka     RK_U32 height       = syntax->height;
375*437bfbebSnyanmisaka     MppFrameFormat fmt  = syntax->format;
376*437bfbebSnyanmisaka     RK_U32 hor_stride   = 0;
377*437bfbebSnyanmisaka     RK_U32 ver_stride   = MPP_ALIGN(height, 16);
378*437bfbebSnyanmisaka     JpegeBits bits      = ctx->bits;
379*437bfbebSnyanmisaka     RK_S32 reg_idx      = task->flags.reg_idx;
380*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)((RK_U8 *)ctx->regs + ctx->reg_size * reg_idx);
381*437bfbebSnyanmisaka     size_t length = mpp_packet_get_length(task->packet);
382*437bfbebSnyanmisaka     RK_U8  *buf = mpp_buffer_get_ptr(output);
383*437bfbebSnyanmisaka     size_t size = mpp_buffer_get_size(output);
384*437bfbebSnyanmisaka     RK_S32 bitpos;
385*437bfbebSnyanmisaka     RK_S32 bytepos;
386*437bfbebSnyanmisaka     RK_U32 x_fill = 0;
387*437bfbebSnyanmisaka     RK_U32 y_fill = 0;
388*437bfbebSnyanmisaka     VepuFormatCfg fmt_cfg;
389*437bfbebSnyanmisaka     RK_U32 rotation = 0;
390*437bfbebSnyanmisaka 
391*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
392*437bfbebSnyanmisaka 
393*437bfbebSnyanmisaka     // do not support mirroring
394*437bfbebSnyanmisaka     if (syntax->mirroring)
395*437bfbebSnyanmisaka         mpp_err_f("Warning: do not support mirroring\n");
396*437bfbebSnyanmisaka 
397*437bfbebSnyanmisaka     if (syntax->rotation == MPP_ENC_ROT_90)
398*437bfbebSnyanmisaka         rotation = 1;
399*437bfbebSnyanmisaka     else if (syntax->rotation == MPP_ENC_ROT_270)
400*437bfbebSnyanmisaka         rotation = 2;
401*437bfbebSnyanmisaka     else if (syntax->rotation != MPP_ENC_ROT_0)
402*437bfbebSnyanmisaka         mpp_err_f("Warning: only support 90 or 270 degree rotate, request rotate %d", syntax->rotation);
403*437bfbebSnyanmisaka     if (rotation) {
404*437bfbebSnyanmisaka         MPP_SWAP(RK_U32, width, height);
405*437bfbebSnyanmisaka         MPP_SWAP(RK_U32, width_align, ver_stride);
406*437bfbebSnyanmisaka     }
407*437bfbebSnyanmisaka     hor_stride = get_vepu_pixel_stride(&ctx->stride_cfg, width,
408*437bfbebSnyanmisaka                                        syntax->hor_stride, fmt);
409*437bfbebSnyanmisaka 
410*437bfbebSnyanmisaka     //hor_stride must be align with 8, and ver_stride mus align with 2
411*437bfbebSnyanmisaka     if ((hor_stride & 0x7) || (ver_stride & 0x1) || (hor_stride >= (1 << 15))) {
412*437bfbebSnyanmisaka         mpp_err_f("illegal resolution, hor_stride %d, ver_stride %d, width %d, height %d\n",
413*437bfbebSnyanmisaka                   syntax->hor_stride, syntax->ver_stride,
414*437bfbebSnyanmisaka                   syntax->width, syntax->height);
415*437bfbebSnyanmisaka     }
416*437bfbebSnyanmisaka 
417*437bfbebSnyanmisaka     x_fill = (width_align - width) / 4;
418*437bfbebSnyanmisaka     y_fill = (ver_stride - height);
419*437bfbebSnyanmisaka     mpp_assert(x_fill <= 3);
420*437bfbebSnyanmisaka     mpp_assert(y_fill <= 15);
421*437bfbebSnyanmisaka     ctx->part_x_fill = x_fill;
422*437bfbebSnyanmisaka     ctx->part_y_fill = y_fill;
423*437bfbebSnyanmisaka 
424*437bfbebSnyanmisaka     mpp_buffer_sync_begin(output);
425*437bfbebSnyanmisaka 
426*437bfbebSnyanmisaka     if (syntax->q_mode == JPEG_QFACTOR) {
427*437bfbebSnyanmisaka         syntax->q_factor = 100 - task->rc_task->info.quality_target;
428*437bfbebSnyanmisaka         hal_jpege_rc_update(&ctx->hal_rc, syntax);
429*437bfbebSnyanmisaka     }
430*437bfbebSnyanmisaka 
431*437bfbebSnyanmisaka     /* write header to output buffer */
432*437bfbebSnyanmisaka     jpege_bits_setup(bits, buf, (RK_U32)size);
433*437bfbebSnyanmisaka     /* seek length bytes data */
434*437bfbebSnyanmisaka     jpege_seek_bits(bits, length << 3);
435*437bfbebSnyanmisaka     /* NOTE: write header will update qtable */
436*437bfbebSnyanmisaka     write_jpeg_header(bits, syntax, &ctx->hal_rc);
437*437bfbebSnyanmisaka 
438*437bfbebSnyanmisaka     memset(regs, 0, sizeof(RK_U32) * VEPU_JPEGE_VEPU2_NUM_REGS);
439*437bfbebSnyanmisaka     // input address setup
440*437bfbebSnyanmisaka     regs[VEPU2_REG_INPUT_Y] = mpp_buffer_get_fd(input);
441*437bfbebSnyanmisaka     regs[VEPU2_REG_INPUT_U] = regs[VEPU2_REG_INPUT_Y];
442*437bfbebSnyanmisaka     regs[VEPU2_REG_INPUT_V] = regs[VEPU2_REG_INPUT_Y];
443*437bfbebSnyanmisaka 
444*437bfbebSnyanmisaka     // output address setup
445*437bfbebSnyanmisaka     bitpos = jpege_bits_get_bitpos(bits);
446*437bfbebSnyanmisaka     bytepos = (bitpos + 7) >> 3;
447*437bfbebSnyanmisaka     ctx->base = buf;
448*437bfbebSnyanmisaka     ctx->size = size;
449*437bfbebSnyanmisaka     ctx->sw_bit = bitpos;
450*437bfbebSnyanmisaka     ctx->part_bytepos = bytepos;
451*437bfbebSnyanmisaka 
452*437bfbebSnyanmisaka     get_msb_lsb_at_pos(&regs[51], &regs[52], buf, bytepos);
453*437bfbebSnyanmisaka 
454*437bfbebSnyanmisaka     mpp_buffer_sync_end(output);
455*437bfbebSnyanmisaka 
456*437bfbebSnyanmisaka     regs[53] = size - bytepos;
457*437bfbebSnyanmisaka 
458*437bfbebSnyanmisaka     // bus config
459*437bfbebSnyanmisaka     regs[54] = 16 << 8;
460*437bfbebSnyanmisaka 
461*437bfbebSnyanmisaka     regs[60] = (((bytepos & 7) * 8) << 16) |
462*437bfbebSnyanmisaka                (x_fill << 4) |
463*437bfbebSnyanmisaka                (y_fill);
464*437bfbebSnyanmisaka     regs[61] = hor_stride;
465*437bfbebSnyanmisaka 
466*437bfbebSnyanmisaka     regs[77] = mpp_buffer_get_fd(output);
467*437bfbebSnyanmisaka     if (bytepos)
468*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(ctx->dev, 77, bytepos);
469*437bfbebSnyanmisaka     /* 95 - 97 color conversion parameter */
470*437bfbebSnyanmisaka     {
471*437bfbebSnyanmisaka         RK_U32 coeffA;
472*437bfbebSnyanmisaka         RK_U32 coeffB;
473*437bfbebSnyanmisaka         RK_U32 coeffC;
474*437bfbebSnyanmisaka         RK_U32 coeffE;
475*437bfbebSnyanmisaka         RK_U32 coeffF;
476*437bfbebSnyanmisaka 
477*437bfbebSnyanmisaka         switch (syntax->color_conversion_type) {
478*437bfbebSnyanmisaka         case 0 : {  /* BT.601 */
479*437bfbebSnyanmisaka             /*
480*437bfbebSnyanmisaka              * Y  = 0.2989 R + 0.5866 G + 0.1145 B
481*437bfbebSnyanmisaka              * Cb = 0.5647 (B - Y) + 128
482*437bfbebSnyanmisaka              * Cr = 0.7132 (R - Y) + 128
483*437bfbebSnyanmisaka              */
484*437bfbebSnyanmisaka             coeffA = 19589;
485*437bfbebSnyanmisaka             coeffB = 38443;
486*437bfbebSnyanmisaka             coeffC = 7504;
487*437bfbebSnyanmisaka             coeffE = 37008;
488*437bfbebSnyanmisaka             coeffF = 46740;
489*437bfbebSnyanmisaka         } break;
490*437bfbebSnyanmisaka         case 1 : {  /* BT.709 */
491*437bfbebSnyanmisaka             /*
492*437bfbebSnyanmisaka              * Y  = 0.2126 R + 0.7152 G + 0.0722 B
493*437bfbebSnyanmisaka              * Cb = 0.5389 (B - Y) + 128
494*437bfbebSnyanmisaka              * Cr = 0.6350 (R - Y) + 128
495*437bfbebSnyanmisaka              */
496*437bfbebSnyanmisaka             coeffA = 13933;
497*437bfbebSnyanmisaka             coeffB = 46871;
498*437bfbebSnyanmisaka             coeffC = 4732;
499*437bfbebSnyanmisaka             coeffE = 35317;
500*437bfbebSnyanmisaka             coeffF = 41615;
501*437bfbebSnyanmisaka         } break;
502*437bfbebSnyanmisaka         case 2 : {
503*437bfbebSnyanmisaka             coeffA = syntax->coeffA;
504*437bfbebSnyanmisaka             coeffB = syntax->coeffB;
505*437bfbebSnyanmisaka             coeffC = syntax->coeffC;
506*437bfbebSnyanmisaka             coeffE = syntax->coeffE;
507*437bfbebSnyanmisaka             coeffF = syntax->coeffF;
508*437bfbebSnyanmisaka         } break;
509*437bfbebSnyanmisaka         default : {
510*437bfbebSnyanmisaka             mpp_err("invalid color conversion type %d\n",
511*437bfbebSnyanmisaka                     syntax->color_conversion_type);
512*437bfbebSnyanmisaka             coeffA = 19589;
513*437bfbebSnyanmisaka             coeffB = 38443;
514*437bfbebSnyanmisaka             coeffC = 7504;
515*437bfbebSnyanmisaka             coeffE = 37008;
516*437bfbebSnyanmisaka             coeffF = 46740;
517*437bfbebSnyanmisaka         } break;
518*437bfbebSnyanmisaka         }
519*437bfbebSnyanmisaka 
520*437bfbebSnyanmisaka         regs[95] = coeffA | (coeffB << 16);
521*437bfbebSnyanmisaka         regs[96] = coeffC | (coeffE << 16);
522*437bfbebSnyanmisaka         regs[97] = coeffF;
523*437bfbebSnyanmisaka     }
524*437bfbebSnyanmisaka 
525*437bfbebSnyanmisaka     regs[103] = (width_align >> 4) << 8  |
526*437bfbebSnyanmisaka                 (ver_stride >> 4) << 20 |
527*437bfbebSnyanmisaka                 (1 << 6) |  /* intra coding  */
528*437bfbebSnyanmisaka                 (2 << 4) |  /* format jpeg   */
529*437bfbebSnyanmisaka                 1;          /* encoder start */
530*437bfbebSnyanmisaka 
531*437bfbebSnyanmisaka     if (!get_vepu_fmt(&fmt_cfg, fmt)) {
532*437bfbebSnyanmisaka         regs[74] = (fmt_cfg.format << 4) |
533*437bfbebSnyanmisaka                    (rotation << 2);
534*437bfbebSnyanmisaka         regs[98] = (fmt_cfg.b_mask & 0x1f) << 16 |
535*437bfbebSnyanmisaka                    (fmt_cfg.g_mask & 0x1f) << 8  |
536*437bfbebSnyanmisaka                    (fmt_cfg.r_mask & 0x1f);
537*437bfbebSnyanmisaka         regs[105] = 7 << 26 | (fmt_cfg.swap_32_in & 1) << 29 |
538*437bfbebSnyanmisaka                     (fmt_cfg.swap_16_in & 1) << 30 |
539*437bfbebSnyanmisaka                     (fmt_cfg.swap_8_in & 1) << 31;
540*437bfbebSnyanmisaka     }
541*437bfbebSnyanmisaka 
542*437bfbebSnyanmisaka     regs[107] = ((syntax->part_rows & 0xff) << 16) |
543*437bfbebSnyanmisaka                 jpege_restart_marker[ctx->rst_marker_idx & 7];
544*437bfbebSnyanmisaka 
545*437bfbebSnyanmisaka     /* encoder interrupt */
546*437bfbebSnyanmisaka     regs[109] = 1 << 12 |   /* clock gating */
547*437bfbebSnyanmisaka                 1 << 10;    /* enable timeout interrupt */
548*437bfbebSnyanmisaka 
549*437bfbebSnyanmisaka     if (syntax->low_delay) {
550*437bfbebSnyanmisaka         /* slice encode end by RST */
551*437bfbebSnyanmisaka         regs[107] |= (1 << 24);
552*437bfbebSnyanmisaka         /* slice interrupt enable */
553*437bfbebSnyanmisaka         regs[109] |= (1 << 16);
554*437bfbebSnyanmisaka     }
555*437bfbebSnyanmisaka 
556*437bfbebSnyanmisaka     /* 0 ~ 31 quantization tables */
557*437bfbebSnyanmisaka     {
558*437bfbebSnyanmisaka         RK_S32 i;
559*437bfbebSnyanmisaka 
560*437bfbebSnyanmisaka         for (i = 0; i < 16; i++) {
561*437bfbebSnyanmisaka             /* qtable need to reorder in particular order */
562*437bfbebSnyanmisaka             regs[i] = ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 0]] << 24 |
563*437bfbebSnyanmisaka                       ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 1]] << 16 |
564*437bfbebSnyanmisaka                       ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 2]] << 8 |
565*437bfbebSnyanmisaka                       ctx->hal_rc.qtables[0][qp_reorder_table[i * 4 + 3]];
566*437bfbebSnyanmisaka         }
567*437bfbebSnyanmisaka         for (i = 0; i < 16; i++) {
568*437bfbebSnyanmisaka             /* qtable need to reorder in particular order */
569*437bfbebSnyanmisaka             regs[i + 16] = ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 0]] << 24 |
570*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 1]] << 16 |
571*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 2]] << 8 |
572*437bfbebSnyanmisaka                            ctx->hal_rc.qtables[1][qp_reorder_table[i * 4 + 3]];
573*437bfbebSnyanmisaka         }
574*437bfbebSnyanmisaka     }
575*437bfbebSnyanmisaka 
576*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
577*437bfbebSnyanmisaka     return MPP_OK;
578*437bfbebSnyanmisaka }
579*437bfbebSnyanmisaka 
multi_core_start(HalJpegeCtx * ctx,HalEncTask * task)580*437bfbebSnyanmisaka static MPP_RET multi_core_start(HalJpegeCtx *ctx, HalEncTask *task)
581*437bfbebSnyanmisaka {
582*437bfbebSnyanmisaka     JpegeMultiCoreCtx *ctx_ext = ctx->ctx_ext;
583*437bfbebSnyanmisaka     JpegeSyntax *syntax = &ctx->syntax;
584*437bfbebSnyanmisaka     MppDevRegOffCfgs *reg_cfg = ctx_ext->reg_cfg;
585*437bfbebSnyanmisaka     MppDev dev = ctx->dev;
586*437bfbebSnyanmisaka     RK_S32 reg_idx = task->flags.reg_idx;
587*437bfbebSnyanmisaka     RK_U32 *src = (RK_U32 *)((RK_U8 *)ctx->regs + ctx->reg_size * reg_idx);
588*437bfbebSnyanmisaka     RK_U32 reg_size = ctx->reg_size;
589*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
590*437bfbebSnyanmisaka     RK_U32 partion_num = ctx_ext->partion_num;
591*437bfbebSnyanmisaka     RK_U32 mcu_y = 0;
592*437bfbebSnyanmisaka     RK_U32 i;
593*437bfbebSnyanmisaka 
594*437bfbebSnyanmisaka     hal_jpege_dbg_detail("start %d partions\n", partion_num);
595*437bfbebSnyanmisaka 
596*437bfbebSnyanmisaka     for (i = 0; i < partion_num; i++) {
597*437bfbebSnyanmisaka         RK_U32 part_not_end = i < partion_num - 1;
598*437bfbebSnyanmisaka         RK_U32 part_not_start = i > 0;
599*437bfbebSnyanmisaka         RK_U32 *regs = (RK_U32 *)ctx_ext->regs[i];
600*437bfbebSnyanmisaka         RK_U32 part_enc_mcu_h = ctx_ext->part_rows[i];
601*437bfbebSnyanmisaka         RK_U32 part_x_fill = ctx->part_x_fill;
602*437bfbebSnyanmisaka         RK_U32 part_y_fill = ctx->part_y_fill;
603*437bfbebSnyanmisaka         RK_U32 part_bytepos = ctx->part_bytepos;
604*437bfbebSnyanmisaka 
605*437bfbebSnyanmisaka         // it only needs to fill the partition on the right and below.
606*437bfbebSnyanmisaka         if (syntax->rotation == MPP_ENC_ROT_90) {
607*437bfbebSnyanmisaka             if (part_not_end)
608*437bfbebSnyanmisaka                 part_x_fill = 0;
609*437bfbebSnyanmisaka         } else if (syntax->rotation == MPP_ENC_ROT_0 || syntax->rotation == MPP_ENC_ROT_180) {
610*437bfbebSnyanmisaka             if (part_not_end)
611*437bfbebSnyanmisaka                 part_y_fill = 0;
612*437bfbebSnyanmisaka         } else if (syntax->rotation == MPP_ENC_ROT_270) {
613*437bfbebSnyanmisaka             if (part_not_start)
614*437bfbebSnyanmisaka                 part_x_fill = 0;
615*437bfbebSnyanmisaka         } else
616*437bfbebSnyanmisaka             mpp_err_f("input rotation %d not supported", syntax->rotation);
617*437bfbebSnyanmisaka 
618*437bfbebSnyanmisaka         memcpy(regs, src, reg_size);
619*437bfbebSnyanmisaka 
620*437bfbebSnyanmisaka         mpp_dev_multi_offset_reset(reg_cfg);
621*437bfbebSnyanmisaka 
622*437bfbebSnyanmisaka         if (i == 0) {
623*437bfbebSnyanmisaka             get_msb_lsb_at_pos(&regs[51], &regs[52], ctx->base, part_bytepos);
624*437bfbebSnyanmisaka             regs[77] = mpp_buffer_get_fd(task->output);
625*437bfbebSnyanmisaka             regs[53] = mpp_buffer_get_size(task->output) - part_bytepos;
626*437bfbebSnyanmisaka             regs[60] = (((part_bytepos & 7) * 8) << 16) |
627*437bfbebSnyanmisaka                        (part_x_fill << 4) |
628*437bfbebSnyanmisaka                        (part_y_fill);
629*437bfbebSnyanmisaka             /* the stream offset had been setup */
630*437bfbebSnyanmisaka         } else {
631*437bfbebSnyanmisaka             MppBuffer buf = ctx_ext->partions_buf[i - 1];
632*437bfbebSnyanmisaka 
633*437bfbebSnyanmisaka             regs[77] = mpp_buffer_get_fd(buf);
634*437bfbebSnyanmisaka             regs[53] = mpp_buffer_get_size(buf);
635*437bfbebSnyanmisaka             regs[60] = (((0 & 7) * 8) << 16) |
636*437bfbebSnyanmisaka                        (part_x_fill << 4) |
637*437bfbebSnyanmisaka                        (part_y_fill);
638*437bfbebSnyanmisaka         }
639*437bfbebSnyanmisaka 
640*437bfbebSnyanmisaka         regs[103] = syntax->mcu_hor_cnt << 8  |
641*437bfbebSnyanmisaka                     (part_enc_mcu_h) << 20 |
642*437bfbebSnyanmisaka                     (1 << 6) |  /* intra coding  */
643*437bfbebSnyanmisaka                     (2 << 4) |  /* format jpeg   */
644*437bfbebSnyanmisaka                     1;          /* encoder start */
645*437bfbebSnyanmisaka 
646*437bfbebSnyanmisaka         hal_jpege_dbg_detail("part %d, part_not_end 0x%x, rst_marker_idx %d",
647*437bfbebSnyanmisaka                              i, part_not_end, ctx->rst_marker_idx);
648*437bfbebSnyanmisaka         regs[107] = part_not_end << 24 | ((syntax->part_rows & 0xff) << 16) |
649*437bfbebSnyanmisaka                     jpege_restart_marker[ctx->rst_marker_idx & 7];
650*437bfbebSnyanmisaka         ctx->rst_marker_idx += ctx_ext->ecs_cnt[i];
651*437bfbebSnyanmisaka 
652*437bfbebSnyanmisaka         VepuOffsetCfg cfg;
653*437bfbebSnyanmisaka 
654*437bfbebSnyanmisaka         memset(&cfg, 0, sizeof(cfg));
655*437bfbebSnyanmisaka 
656*437bfbebSnyanmisaka         cfg.fmt = syntax->format;
657*437bfbebSnyanmisaka         cfg.width = syntax->width;
658*437bfbebSnyanmisaka         cfg.height = syntax->height;
659*437bfbebSnyanmisaka         cfg.hor_stride = syntax->hor_stride;
660*437bfbebSnyanmisaka         cfg.ver_stride = syntax->ver_stride;
661*437bfbebSnyanmisaka         cfg.offset_x = syntax->offset_x;
662*437bfbebSnyanmisaka         cfg.offset_y = syntax->offset_y + mcu_y * 16;
663*437bfbebSnyanmisaka 
664*437bfbebSnyanmisaka         if (syntax->rotation == MPP_ENC_ROT_90 || syntax->rotation == MPP_ENC_ROT_270) {
665*437bfbebSnyanmisaka             regs[103] = part_enc_mcu_h << 8  |
666*437bfbebSnyanmisaka                         (syntax->mcu_hor_cnt) << 20 |
667*437bfbebSnyanmisaka                         (1 << 6) |  /* intra coding  */
668*437bfbebSnyanmisaka                         (2 << 4) |  /* format jpeg   */
669*437bfbebSnyanmisaka                         1;          /* encoder start */
670*437bfbebSnyanmisaka 
671*437bfbebSnyanmisaka             /*
672*437bfbebSnyanmisaka              * It is opposite that position of partitions
673*437bfbebSnyanmisaka              * of rotation 90 degree and rotation 270 degree.
674*437bfbebSnyanmisaka              */
675*437bfbebSnyanmisaka             if (syntax->rotation == MPP_ENC_ROT_270)
676*437bfbebSnyanmisaka                 cfg.offset_x = syntax->offset_x +
677*437bfbebSnyanmisaka                                (syntax->mcu_ver_cnt - ctx_ext->part_rows[0] - mcu_y) * 16;
678*437bfbebSnyanmisaka             else
679*437bfbebSnyanmisaka                 cfg.offset_x = syntax->offset_x + mcu_y * 16;
680*437bfbebSnyanmisaka 
681*437bfbebSnyanmisaka             cfg.offset_y = syntax->offset_y;
682*437bfbebSnyanmisaka         }
683*437bfbebSnyanmisaka 
684*437bfbebSnyanmisaka         get_vepu_offset_cfg(&cfg);
685*437bfbebSnyanmisaka         mpp_dev_multi_offset_update(reg_cfg, VEPU2_REG_INPUT_Y, cfg.offset_byte[0]);
686*437bfbebSnyanmisaka         mpp_dev_multi_offset_update(reg_cfg, VEPU2_REG_INPUT_U, cfg.offset_byte[1]);
687*437bfbebSnyanmisaka         mpp_dev_multi_offset_update(reg_cfg, VEPU2_REG_INPUT_V, cfg.offset_byte[2]);
688*437bfbebSnyanmisaka 
689*437bfbebSnyanmisaka         mcu_y += part_enc_mcu_h;
690*437bfbebSnyanmisaka 
691*437bfbebSnyanmisaka         do {
692*437bfbebSnyanmisaka             MppDevRegWrCfg wr_cfg;
693*437bfbebSnyanmisaka             MppDevRegRdCfg rd_cfg;
694*437bfbebSnyanmisaka 
695*437bfbebSnyanmisaka             wr_cfg.reg = regs;
696*437bfbebSnyanmisaka             wr_cfg.size = reg_size;
697*437bfbebSnyanmisaka             wr_cfg.offset = 0;
698*437bfbebSnyanmisaka 
699*437bfbebSnyanmisaka             ret = mpp_dev_ioctl(dev, MPP_DEV_REG_WR, &wr_cfg);
700*437bfbebSnyanmisaka             if (ret) {
701*437bfbebSnyanmisaka                 mpp_err_f("set register write failed %d\n", ret);
702*437bfbebSnyanmisaka                 break;
703*437bfbebSnyanmisaka             }
704*437bfbebSnyanmisaka 
705*437bfbebSnyanmisaka             rd_cfg.reg = ctx_ext->regs_out[i];
706*437bfbebSnyanmisaka             rd_cfg.size = reg_size;
707*437bfbebSnyanmisaka             rd_cfg.offset = 0;
708*437bfbebSnyanmisaka 
709*437bfbebSnyanmisaka             ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
710*437bfbebSnyanmisaka             if (ret) {
711*437bfbebSnyanmisaka                 mpp_err_f("set register read failed %d\n", ret);
712*437bfbebSnyanmisaka                 break;
713*437bfbebSnyanmisaka             }
714*437bfbebSnyanmisaka 
715*437bfbebSnyanmisaka             ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFS, reg_cfg);
716*437bfbebSnyanmisaka             if (ret) {
717*437bfbebSnyanmisaka                 mpp_err_f("set register offsets failed %d\n", ret);
718*437bfbebSnyanmisaka                 break;
719*437bfbebSnyanmisaka             }
720*437bfbebSnyanmisaka 
721*437bfbebSnyanmisaka             if (i < partion_num - 1) {
722*437bfbebSnyanmisaka                 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_DELIMIT, NULL);
723*437bfbebSnyanmisaka                 if (ret) {
724*437bfbebSnyanmisaka                     mpp_err_f("send delimit failed %d\n", ret);
725*437bfbebSnyanmisaka                     break;
726*437bfbebSnyanmisaka                 }
727*437bfbebSnyanmisaka             }
728*437bfbebSnyanmisaka         } while (0);
729*437bfbebSnyanmisaka     }
730*437bfbebSnyanmisaka 
731*437bfbebSnyanmisaka     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
732*437bfbebSnyanmisaka     if (ret)
733*437bfbebSnyanmisaka         mpp_err_f("send cmd failed %d\n", ret);
734*437bfbebSnyanmisaka 
735*437bfbebSnyanmisaka     return ret;
736*437bfbebSnyanmisaka }
737*437bfbebSnyanmisaka 
multi_core_wait(HalJpegeCtx * ctx,HalEncTask * task)738*437bfbebSnyanmisaka static MPP_RET multi_core_wait(HalJpegeCtx *ctx, HalEncTask *task)
739*437bfbebSnyanmisaka {
740*437bfbebSnyanmisaka     JpegeMultiCoreCtx *ctx_ext = (JpegeMultiCoreCtx *)ctx->ctx_ext;
741*437bfbebSnyanmisaka     JpegeFeedback *feedback = &ctx->feedback;
742*437bfbebSnyanmisaka     RK_U32 sw_bit = 0;
743*437bfbebSnyanmisaka     RK_U32 hw_bit = 0;
744*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
745*437bfbebSnyanmisaka     RK_U32 val;
746*437bfbebSnyanmisaka     RK_U32 i;
747*437bfbebSnyanmisaka 
748*437bfbebSnyanmisaka     hal_jpege_dbg_detail("poll partion_num %d\n", ctx_ext->partion_num);
749*437bfbebSnyanmisaka 
750*437bfbebSnyanmisaka     for (i = 0; i < ctx_ext->partion_num; i++) {
751*437bfbebSnyanmisaka         RK_U32 *regs = ctx_ext->regs_out[i];
752*437bfbebSnyanmisaka 
753*437bfbebSnyanmisaka         hal_jpege_dbg_detail("poll reg %d %p", i, regs);
754*437bfbebSnyanmisaka 
755*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
756*437bfbebSnyanmisaka         if (ret)
757*437bfbebSnyanmisaka             mpp_err_f("poll cmd failed %d\n", ret);
758*437bfbebSnyanmisaka 
759*437bfbebSnyanmisaka         if (i == 0) {
760*437bfbebSnyanmisaka             RK_S32 fd = mpp_buffer_get_fd(task->output);
761*437bfbebSnyanmisaka 
762*437bfbebSnyanmisaka             val = regs[109];
763*437bfbebSnyanmisaka             hal_jpege_dbg_output("hw_status %08x\n", val);
764*437bfbebSnyanmisaka             feedback->hw_status = val & 0x70;
765*437bfbebSnyanmisaka             val = regs[53];
766*437bfbebSnyanmisaka             sw_bit = jpege_bits_get_bitpos(ctx->bits);
767*437bfbebSnyanmisaka             hw_bit = val;
768*437bfbebSnyanmisaka             feedback->stream_length = ((sw_bit / 8) & (~0x7)) + hw_bit / 8;
769*437bfbebSnyanmisaka             hal_jpege_dbg_detail("partion len = %d", hw_bit / 8);
770*437bfbebSnyanmisaka             task->length = feedback->stream_length;
771*437bfbebSnyanmisaka             task->hw_length = task->length - ctx->hal_start_pos;
772*437bfbebSnyanmisaka 
773*437bfbebSnyanmisaka             mpp_dmabuf_sync_partial_begin(fd, 1, 0, task->length, __FUNCTION__);
774*437bfbebSnyanmisaka         } else {
775*437bfbebSnyanmisaka             void *stream_ptr = mpp_buffer_get_ptr(task->output);
776*437bfbebSnyanmisaka             void *partion_ptr = mpp_buffer_get_ptr(ctx_ext->partions_buf[i - 1]);
777*437bfbebSnyanmisaka             RK_S32 partion_fd = mpp_buffer_get_fd(ctx_ext->partions_buf[i - 1]);
778*437bfbebSnyanmisaka             RK_U32 partion_len = 0;
779*437bfbebSnyanmisaka 
780*437bfbebSnyanmisaka             val = regs[109];
781*437bfbebSnyanmisaka             hal_jpege_dbg_output("hw_status %08x\n", val);
782*437bfbebSnyanmisaka             feedback->hw_status = val & 0x70;
783*437bfbebSnyanmisaka             partion_len = regs[53] / 8;
784*437bfbebSnyanmisaka             hal_jpege_dbg_detail("partion_len = %d", partion_len);
785*437bfbebSnyanmisaka 
786*437bfbebSnyanmisaka             mpp_dmabuf_sync_partial_begin(partion_fd, 1, 0, partion_len, __FUNCTION__);
787*437bfbebSnyanmisaka 
788*437bfbebSnyanmisaka             memcpy(stream_ptr + feedback->stream_length, partion_ptr, partion_len);
789*437bfbebSnyanmisaka             feedback->stream_length += partion_len;
790*437bfbebSnyanmisaka             task->length = feedback->stream_length;
791*437bfbebSnyanmisaka             task->hw_length += partion_len;
792*437bfbebSnyanmisaka         }
793*437bfbebSnyanmisaka     }
794*437bfbebSnyanmisaka 
795*437bfbebSnyanmisaka     hal_jpege_dbg_output("stream bit: sw %d hw %d total %d hw_length %d\n",
796*437bfbebSnyanmisaka                          sw_bit, hw_bit, feedback->stream_length, task->hw_length);
797*437bfbebSnyanmisaka 
798*437bfbebSnyanmisaka     return ret;
799*437bfbebSnyanmisaka }
800*437bfbebSnyanmisaka 
hal_jpege_vepu2_start(void * hal,HalEncTask * task)801*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_start(void *hal, HalEncTask *task)
802*437bfbebSnyanmisaka {
803*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
804*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
805*437bfbebSnyanmisaka     JpegeMultiCoreCtx *ctx_ext = (JpegeMultiCoreCtx *)ctx->ctx_ext;
806*437bfbebSnyanmisaka 
807*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
808*437bfbebSnyanmisaka 
809*437bfbebSnyanmisaka     if (ctx_ext && ctx_ext->multi_core_enabled) {
810*437bfbebSnyanmisaka         multi_core_start(ctx, task);
811*437bfbebSnyanmisaka     } else {
812*437bfbebSnyanmisaka         hal_jpege_vepu2_set_extra_info(ctx->dev, &ctx->syntax, 0);
813*437bfbebSnyanmisaka         do {
814*437bfbebSnyanmisaka             MppDevRegWrCfg wr_cfg;
815*437bfbebSnyanmisaka             MppDevRegRdCfg rd_cfg;
816*437bfbebSnyanmisaka             RK_U32 reg_size = ctx->reg_size;
817*437bfbebSnyanmisaka             RK_S32 reg_idx = task->flags.reg_idx;
818*437bfbebSnyanmisaka             RK_U32 *regs = (RK_U32 *)((RK_U8 *)ctx->regs + reg_size * reg_idx);
819*437bfbebSnyanmisaka 
820*437bfbebSnyanmisaka             wr_cfg.reg = regs;
821*437bfbebSnyanmisaka             wr_cfg.size = reg_size;
822*437bfbebSnyanmisaka             wr_cfg.offset = 0;
823*437bfbebSnyanmisaka 
824*437bfbebSnyanmisaka             ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
825*437bfbebSnyanmisaka             if (ret) {
826*437bfbebSnyanmisaka                 mpp_err_f("set register write failed %d\n", ret);
827*437bfbebSnyanmisaka                 break;
828*437bfbebSnyanmisaka             }
829*437bfbebSnyanmisaka 
830*437bfbebSnyanmisaka             rd_cfg.reg = regs;
831*437bfbebSnyanmisaka             rd_cfg.size = reg_size;
832*437bfbebSnyanmisaka             rd_cfg.offset = 0;
833*437bfbebSnyanmisaka 
834*437bfbebSnyanmisaka             ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
835*437bfbebSnyanmisaka             if (ret) {
836*437bfbebSnyanmisaka                 mpp_err_f("set register read failed %d\n", ret);
837*437bfbebSnyanmisaka                 break;
838*437bfbebSnyanmisaka             }
839*437bfbebSnyanmisaka 
840*437bfbebSnyanmisaka             ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
841*437bfbebSnyanmisaka             if (ret) {
842*437bfbebSnyanmisaka                 mpp_err_f("send cmd failed %d\n", ret);
843*437bfbebSnyanmisaka                 break;
844*437bfbebSnyanmisaka             }
845*437bfbebSnyanmisaka         } while (0);
846*437bfbebSnyanmisaka     }
847*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
848*437bfbebSnyanmisaka     (void)task;
849*437bfbebSnyanmisaka     return ret;
850*437bfbebSnyanmisaka }
851*437bfbebSnyanmisaka 
hal_jpege_vepu2_wait(void * hal,HalEncTask * task)852*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_wait(void *hal, HalEncTask *task)
853*437bfbebSnyanmisaka {
854*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
855*437bfbebSnyanmisaka     JpegeMultiCoreCtx *ctx_ext = (JpegeMultiCoreCtx *)ctx->ctx_ext;
856*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
857*437bfbebSnyanmisaka 
858*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter hal %p\n", hal);
859*437bfbebSnyanmisaka 
860*437bfbebSnyanmisaka     if (ctx_ext && ctx_ext->multi_core_enabled) {
861*437bfbebSnyanmisaka         multi_core_wait(ctx, task);
862*437bfbebSnyanmisaka     } else {
863*437bfbebSnyanmisaka         JpegeFeedback *feedback = &ctx->feedback;
864*437bfbebSnyanmisaka         JpegeBits bits = ctx->bits;
865*437bfbebSnyanmisaka         RK_S32 reg_idx = task->flags.reg_idx;
866*437bfbebSnyanmisaka         RK_U32 *regs = (RK_U32 *)((RK_U8 *)ctx->regs + ctx->reg_size * reg_idx);
867*437bfbebSnyanmisaka         RK_U32 sw_bit = 0;
868*437bfbebSnyanmisaka         RK_U32 hw_bit = 0;
869*437bfbebSnyanmisaka         RK_U32 val;
870*437bfbebSnyanmisaka 
871*437bfbebSnyanmisaka         if (ctx->dev) {
872*437bfbebSnyanmisaka             ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
873*437bfbebSnyanmisaka             if (ret)
874*437bfbebSnyanmisaka                 mpp_err_f("poll cmd failed %d\n", ret);
875*437bfbebSnyanmisaka         }
876*437bfbebSnyanmisaka 
877*437bfbebSnyanmisaka         val = regs[109];
878*437bfbebSnyanmisaka         hal_jpege_dbg_output("hw_status %08x\n", val);
879*437bfbebSnyanmisaka         feedback->hw_status = val & 0x70;
880*437bfbebSnyanmisaka         val = regs[53];
881*437bfbebSnyanmisaka 
882*437bfbebSnyanmisaka         sw_bit = jpege_bits_get_bitpos(bits);
883*437bfbebSnyanmisaka         hw_bit = val;
884*437bfbebSnyanmisaka 
885*437bfbebSnyanmisaka         // NOTE: hardware will return 64 bit access byte count
886*437bfbebSnyanmisaka         feedback->stream_length = ((sw_bit / 8) & (~0x7)) + hw_bit / 8;
887*437bfbebSnyanmisaka         task->length = feedback->stream_length;
888*437bfbebSnyanmisaka         task->hw_length = task->length - ctx->hal_start_pos;
889*437bfbebSnyanmisaka 
890*437bfbebSnyanmisaka         hal_jpege_dbg_output("stream bit: sw %d hw %d total %d hw_length %d\n",
891*437bfbebSnyanmisaka                              sw_bit, hw_bit, feedback->stream_length, task->hw_length);
892*437bfbebSnyanmisaka     }
893*437bfbebSnyanmisaka 
894*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave hal %p\n", hal);
895*437bfbebSnyanmisaka     return ret;
896*437bfbebSnyanmisaka }
897*437bfbebSnyanmisaka 
hal_jpege_vepu2_part_start(void * hal,HalEncTask * task)898*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_part_start(void *hal, HalEncTask *task)
899*437bfbebSnyanmisaka {
900*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
901*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
902*437bfbebSnyanmisaka     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
903*437bfbebSnyanmisaka     RK_U32 mcu_w = syntax->mcu_hor_cnt;
904*437bfbebSnyanmisaka     RK_U32 mcu_h = syntax->mcu_ver_cnt;
905*437bfbebSnyanmisaka     RK_U32 mcu_y = ctx->mcu_y;
906*437bfbebSnyanmisaka     RK_U32 part_mcu_h = syntax->part_rows;
907*437bfbebSnyanmisaka     RK_S32 reg_idx = task->flags.reg_idx;
908*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)((RK_U8 *)ctx->regs + ctx->reg_size * reg_idx);
909*437bfbebSnyanmisaka     RK_U32 part_enc_h;
910*437bfbebSnyanmisaka     RK_U32 part_enc_mcu_h;
911*437bfbebSnyanmisaka     RK_U32 part_y_fill;
912*437bfbebSnyanmisaka     RK_U32 part_not_end;
913*437bfbebSnyanmisaka 
914*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter part start %p\n", hal);
915*437bfbebSnyanmisaka 
916*437bfbebSnyanmisaka     /* Fix register for each part encoding */
917*437bfbebSnyanmisaka     task->part_first = !mcu_y;
918*437bfbebSnyanmisaka     if (mcu_y + part_mcu_h < mcu_h) {
919*437bfbebSnyanmisaka         part_enc_h = part_mcu_h * 16;
920*437bfbebSnyanmisaka         part_enc_mcu_h = part_mcu_h;
921*437bfbebSnyanmisaka         part_y_fill = 0;
922*437bfbebSnyanmisaka         part_not_end = 1;
923*437bfbebSnyanmisaka         task->part_last = 0;
924*437bfbebSnyanmisaka     } else {
925*437bfbebSnyanmisaka         part_enc_h = syntax->height - mcu_y * 16;
926*437bfbebSnyanmisaka         part_enc_mcu_h = MPP_ALIGN(part_enc_h, 16) / 16;;
927*437bfbebSnyanmisaka         part_y_fill = ctx->part_y_fill;
928*437bfbebSnyanmisaka         part_not_end = 0;
929*437bfbebSnyanmisaka         task->part_last = 1;
930*437bfbebSnyanmisaka     }
931*437bfbebSnyanmisaka 
932*437bfbebSnyanmisaka     hal_jpege_dbg_detail("part first %d last %d\n", task->part_first, task->part_last);
933*437bfbebSnyanmisaka 
934*437bfbebSnyanmisaka     get_msb_lsb_at_pos(&regs[51], &regs[52], ctx->base, ctx->part_bytepos);
935*437bfbebSnyanmisaka 
936*437bfbebSnyanmisaka     regs[53] = ctx->size - ctx->part_bytepos;
937*437bfbebSnyanmisaka 
938*437bfbebSnyanmisaka     regs[60] = (((ctx->part_bytepos & 7) * 8) << 16) |
939*437bfbebSnyanmisaka                (ctx->part_x_fill << 4) |
940*437bfbebSnyanmisaka                (part_y_fill);
941*437bfbebSnyanmisaka 
942*437bfbebSnyanmisaka     regs[77] = mpp_buffer_get_fd(task->output);
943*437bfbebSnyanmisaka     if (ctx->part_bytepos)
944*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(ctx->dev, 77, ctx->part_bytepos);
945*437bfbebSnyanmisaka 
946*437bfbebSnyanmisaka     regs[103] = mcu_w << 8  |
947*437bfbebSnyanmisaka                 (part_enc_mcu_h) << 20 |
948*437bfbebSnyanmisaka                 (1 << 6) |  /* intra coding  */
949*437bfbebSnyanmisaka                 (2 << 4) |  /* format jpeg   */
950*437bfbebSnyanmisaka                 1;          /* encoder start */
951*437bfbebSnyanmisaka 
952*437bfbebSnyanmisaka     hal_jpege_dbg_detail("part_not_end 0x%x, rst_marker_idx %d",
953*437bfbebSnyanmisaka                          part_not_end, ctx->rst_marker_idx);
954*437bfbebSnyanmisaka     regs[107] = part_not_end << 24 | jpege_restart_marker[ctx->rst_marker_idx & 7];
955*437bfbebSnyanmisaka     ctx->rst_marker_idx++;
956*437bfbebSnyanmisaka 
957*437bfbebSnyanmisaka     hal_jpege_vepu2_set_extra_info(ctx->dev, syntax, mcu_y);
958*437bfbebSnyanmisaka     ctx->mcu_y += part_enc_mcu_h;
959*437bfbebSnyanmisaka 
960*437bfbebSnyanmisaka     do {
961*437bfbebSnyanmisaka         MppDevRegWrCfg wr_cfg;
962*437bfbebSnyanmisaka         MppDevRegRdCfg rd_cfg;
963*437bfbebSnyanmisaka         RK_U32 reg_size = ctx->reg_size;
964*437bfbebSnyanmisaka 
965*437bfbebSnyanmisaka         wr_cfg.reg = ctx->regs;
966*437bfbebSnyanmisaka         wr_cfg.size = reg_size;
967*437bfbebSnyanmisaka         wr_cfg.offset = 0;
968*437bfbebSnyanmisaka 
969*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
970*437bfbebSnyanmisaka         if (ret) {
971*437bfbebSnyanmisaka             mpp_err_f("set register write failed %d\n", ret);
972*437bfbebSnyanmisaka             break;
973*437bfbebSnyanmisaka         }
974*437bfbebSnyanmisaka 
975*437bfbebSnyanmisaka         rd_cfg.reg = ctx->regs_out;
976*437bfbebSnyanmisaka         rd_cfg.size = reg_size;
977*437bfbebSnyanmisaka         rd_cfg.offset = 0;
978*437bfbebSnyanmisaka 
979*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
980*437bfbebSnyanmisaka         if (ret) {
981*437bfbebSnyanmisaka             mpp_err_f("set register read failed %d\n", ret);
982*437bfbebSnyanmisaka             break;
983*437bfbebSnyanmisaka         }
984*437bfbebSnyanmisaka 
985*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
986*437bfbebSnyanmisaka         if (ret) {
987*437bfbebSnyanmisaka             mpp_err_f("send cmd failed %d\n", ret);
988*437bfbebSnyanmisaka             break;
989*437bfbebSnyanmisaka         }
990*437bfbebSnyanmisaka     } while (0);
991*437bfbebSnyanmisaka 
992*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave part start %p\n", hal);
993*437bfbebSnyanmisaka     (void)task;
994*437bfbebSnyanmisaka     return ret;
995*437bfbebSnyanmisaka }
996*437bfbebSnyanmisaka 
hal_jpege_vepu2_part_wait(void * hal,HalEncTask * task)997*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_part_wait(void *hal, HalEncTask *task)
998*437bfbebSnyanmisaka {
999*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
1000*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
1001*437bfbebSnyanmisaka     RK_S32 reg_idx = task->flags.reg_idx;
1002*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)((RK_U8 *)ctx->regs_out + ctx->reg_size * reg_idx);
1003*437bfbebSnyanmisaka     JpegeFeedback *feedback = &ctx->feedback;
1004*437bfbebSnyanmisaka     RK_U32 hw_bit = 0;
1005*437bfbebSnyanmisaka 
1006*437bfbebSnyanmisaka     hal_jpege_dbg_func("enter part wait %p\n", hal);
1007*437bfbebSnyanmisaka 
1008*437bfbebSnyanmisaka     if (ctx->dev) {
1009*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
1010*437bfbebSnyanmisaka         if (ret)
1011*437bfbebSnyanmisaka             mpp_err_f("poll cmd failed %d\n", ret);
1012*437bfbebSnyanmisaka     }
1013*437bfbebSnyanmisaka 
1014*437bfbebSnyanmisaka     hal_jpege_dbg_detail("hw_status %08x\n", regs[109]);
1015*437bfbebSnyanmisaka 
1016*437bfbebSnyanmisaka     hw_bit = regs[53];
1017*437bfbebSnyanmisaka 
1018*437bfbebSnyanmisaka     hal_jpege_dbg_detail("byte pos %d -> %d\n", ctx->part_bytepos,
1019*437bfbebSnyanmisaka                          (ctx->part_bytepos & (~7)) + (hw_bit / 8));
1020*437bfbebSnyanmisaka     ctx->part_bytepos = (ctx->part_bytepos & (~7)) + (hw_bit / 8);
1021*437bfbebSnyanmisaka 
1022*437bfbebSnyanmisaka     feedback->stream_length = ctx->part_bytepos;
1023*437bfbebSnyanmisaka     task->length = ctx->part_bytepos;
1024*437bfbebSnyanmisaka     task->hw_length = task->length - ctx->hal_start_pos;
1025*437bfbebSnyanmisaka 
1026*437bfbebSnyanmisaka     hal_jpege_dbg_detail("stream_length %d, hw_byte %d",
1027*437bfbebSnyanmisaka                          feedback->stream_length, hw_bit / 8);
1028*437bfbebSnyanmisaka 
1029*437bfbebSnyanmisaka     hal_jpege_dbg_output("stream bit: sw %d hw %d total %d hw_length %d\n",
1030*437bfbebSnyanmisaka                          ctx->sw_bit, hw_bit, feedback->stream_length, task->hw_length);
1031*437bfbebSnyanmisaka 
1032*437bfbebSnyanmisaka     hal_jpege_dbg_func("leave part wait %p\n", hal);
1033*437bfbebSnyanmisaka     return ret;
1034*437bfbebSnyanmisaka }
1035*437bfbebSnyanmisaka 
hal_jpege_vepu2_ret_task(void * hal,HalEncTask * task)1036*437bfbebSnyanmisaka MPP_RET hal_jpege_vepu2_ret_task(void *hal, HalEncTask *task)
1037*437bfbebSnyanmisaka {
1038*437bfbebSnyanmisaka     HalJpegeCtx *ctx = (HalJpegeCtx *)hal;
1039*437bfbebSnyanmisaka     EncRcTaskInfo *rc_info = &task->rc_task->info;
1040*437bfbebSnyanmisaka 
1041*437bfbebSnyanmisaka     task->rc_task->info.bit_real = ctx->feedback.stream_length * 8;
1042*437bfbebSnyanmisaka     task->hal_ret.data = &ctx->feedback;
1043*437bfbebSnyanmisaka     task->hal_ret.number = 1;
1044*437bfbebSnyanmisaka 
1045*437bfbebSnyanmisaka     rc_info->quality_real = rc_info->quality_target;
1046*437bfbebSnyanmisaka 
1047*437bfbebSnyanmisaka     return MPP_OK;
1048*437bfbebSnyanmisaka }
1049*437bfbebSnyanmisaka 
1050*437bfbebSnyanmisaka const MppEncHalApi hal_jpege_vepu2 = {
1051*437bfbebSnyanmisaka     .name       = "hal_jpege_vepu2",
1052*437bfbebSnyanmisaka     .coding     = MPP_VIDEO_CodingMJPEG,
1053*437bfbebSnyanmisaka     .ctx_size   = sizeof(HalJpegeCtx),
1054*437bfbebSnyanmisaka     .flag       = 0,
1055*437bfbebSnyanmisaka     .init       = hal_jpege_vepu2_init,
1056*437bfbebSnyanmisaka     .deinit     = hal_jpege_vepu2_deinit,
1057*437bfbebSnyanmisaka     .prepare    = NULL,
1058*437bfbebSnyanmisaka     .get_task   = hal_jpege_vepu2_get_task,
1059*437bfbebSnyanmisaka     .gen_regs   = hal_jpege_vepu2_gen_regs,
1060*437bfbebSnyanmisaka     .start      = hal_jpege_vepu2_start,
1061*437bfbebSnyanmisaka     .wait       = hal_jpege_vepu2_wait,
1062*437bfbebSnyanmisaka     .part_start = hal_jpege_vepu2_part_start,
1063*437bfbebSnyanmisaka     .part_wait  = hal_jpege_vepu2_part_wait,
1064*437bfbebSnyanmisaka     .ret_task   = hal_jpege_vepu2_ret_task,
1065*437bfbebSnyanmisaka };
1066