xref: /rockchip-linux_mpp/mpp/hal/vpu/jpegd/hal_jpegd_vdpu2.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  *
3*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
4*437bfbebSnyanmisaka  *
5*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
6*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
7*437bfbebSnyanmisaka  * You may obtain a copy of the License at
8*437bfbebSnyanmisaka  *
9*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
10*437bfbebSnyanmisaka  *
11*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
12*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
13*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
15*437bfbebSnyanmisaka  * limitations under the License.
16*437bfbebSnyanmisaka  */
17*437bfbebSnyanmisaka #define MODULE_TAG "HAL_JPEG_VDPU2"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <stdio.h>
20*437bfbebSnyanmisaka #include <string.h>
21*437bfbebSnyanmisaka #include <stdint.h>
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka #include "mpp_env.h"
24*437bfbebSnyanmisaka #include "mpp_mem.h"
25*437bfbebSnyanmisaka #include "mpp_debug.h"
26*437bfbebSnyanmisaka #include "mpp_frame.h"
27*437bfbebSnyanmisaka #include "mpp_common.h"
28*437bfbebSnyanmisaka 
29*437bfbebSnyanmisaka #include "jpegd_syntax.h"
30*437bfbebSnyanmisaka #include "hal_jpegd_common.h"
31*437bfbebSnyanmisaka #include "hal_jpegd_vdpu2.h"
32*437bfbebSnyanmisaka #include "hal_jpegd_vdpu2_reg.h"
33*437bfbebSnyanmisaka #include "mpp_dec_cb_param.h"
34*437bfbebSnyanmisaka 
35*437bfbebSnyanmisaka extern RK_U32 jpegd_debug;
36*437bfbebSnyanmisaka 
jpegd_regs_init(JpegRegSet * reg)37*437bfbebSnyanmisaka static MPP_RET jpegd_regs_init(JpegRegSet *reg)
38*437bfbebSnyanmisaka {
39*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
40*437bfbebSnyanmisaka     memset(reg, 0, sizeof(JpegRegSet));
41*437bfbebSnyanmisaka     reg->reg50_dec_ctrl.sw_dec_out_tiled_e = 0;
42*437bfbebSnyanmisaka     reg->reg50_dec_ctrl.sw_dec_scmd_dis = DEC_SCMD_DISABLE;
43*437bfbebSnyanmisaka     reg->reg50_dec_ctrl.sw_dec_latency = DEC_LATENCY_COMPENSATION;
44*437bfbebSnyanmisaka 
45*437bfbebSnyanmisaka     reg->reg54_endian.sw_dec_in_endian = DEC_BIG_ENDIAN;
46*437bfbebSnyanmisaka     reg->reg54_endian.sw_dec_out_endian = DEC_LITTLE_ENDIAN;
47*437bfbebSnyanmisaka     reg->reg54_endian.sw_dec_strendian_e = DEC_LITTLE_ENDIAN;
48*437bfbebSnyanmisaka     reg->reg54_endian.sw_dec_outswap32_e = DEC_LITTLE_ENDIAN;
49*437bfbebSnyanmisaka     reg->reg54_endian.sw_dec_inswap32_e = 1;
50*437bfbebSnyanmisaka     reg->reg54_endian.sw_dec_strswap32_e = 1;
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka     reg->reg55_Interrupt.sw_dec_irq_dis = 0;
53*437bfbebSnyanmisaka 
54*437bfbebSnyanmisaka     reg->reg56_axi_ctrl.sw_dec_axi_rn_id = 0xff;
55*437bfbebSnyanmisaka     reg->reg56_axi_ctrl.sw_dec_axi_wr_id = 0;
56*437bfbebSnyanmisaka     reg->reg56_axi_ctrl.sw_dec_max_burst = DEC_BUS_BURST_LENGTH_16;
57*437bfbebSnyanmisaka     reg->reg56_axi_ctrl.sw_dec_data_disc_e = DEC_DATA_DISCARD_ENABLE;
58*437bfbebSnyanmisaka 
59*437bfbebSnyanmisaka     reg->reg57_enable_ctrl.sw_dec_timeout_e = 1;
60*437bfbebSnyanmisaka     reg->reg57_enable_ctrl.sw_dec_clk_gate_e = 1;
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
63*437bfbebSnyanmisaka     return MPP_OK;
64*437bfbebSnyanmisaka }
65*437bfbebSnyanmisaka 
jpegd_write_code_word_number(JpegdHalCtx * ctx,JpegdSyntax * syntax)66*437bfbebSnyanmisaka static void jpegd_write_code_word_number(JpegdHalCtx *ctx,
67*437bfbebSnyanmisaka                                          JpegdSyntax *syntax)
68*437bfbebSnyanmisaka {
69*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
70*437bfbebSnyanmisaka     JpegdSyntax *s = syntax;
71*437bfbebSnyanmisaka     AcTable *ac_ptr0 = NULL, *ac_ptr1 = NULL;
72*437bfbebSnyanmisaka     DcTable *dc_ptr0 = NULL, *dc_ptr1 = NULL;
73*437bfbebSnyanmisaka     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
74*437bfbebSnyanmisaka     JpegRegSet *reg = &(info->regs);
75*437bfbebSnyanmisaka 
76*437bfbebSnyanmisaka     /* first, select the table we'll use.
77*437bfbebSnyanmisaka      * this trick is done because hardware always wants luma
78*437bfbebSnyanmisaka      * table as AC hardware table 0.
79*437bfbebSnyanmisaka      */
80*437bfbebSnyanmisaka     if (s->ac_index[0] == HUFFMAN_TABLE_ID_ZERO) {
81*437bfbebSnyanmisaka         /* Luma's AC uses Huffman table zero */
82*437bfbebSnyanmisaka         ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
83*437bfbebSnyanmisaka         ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
84*437bfbebSnyanmisaka     } else {
85*437bfbebSnyanmisaka         ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
86*437bfbebSnyanmisaka         ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
87*437bfbebSnyanmisaka     }
88*437bfbebSnyanmisaka 
89*437bfbebSnyanmisaka     /* write AC table 0 (luma) */
90*437bfbebSnyanmisaka     reg->reg134.sw_ac1_code1_cnt = ac_ptr0->bits[0];
91*437bfbebSnyanmisaka     reg->reg134.sw_ac1_code2_cnt = ac_ptr0->bits[1];
92*437bfbebSnyanmisaka     reg->reg134.sw_ac1_code3_cnt = ac_ptr0->bits[2];
93*437bfbebSnyanmisaka     reg->reg134.sw_ac1_code4_cnt = ac_ptr0->bits[3];
94*437bfbebSnyanmisaka     reg->reg134.sw_ac1_code5_cnt = ac_ptr0->bits[4];
95*437bfbebSnyanmisaka     reg->reg134.sw_ac1_code6_cnt = ac_ptr0->bits[5];
96*437bfbebSnyanmisaka 
97*437bfbebSnyanmisaka     reg->reg135.sw_ac1_code7_cnt = ac_ptr0->bits[6];
98*437bfbebSnyanmisaka     reg->reg135.sw_ac1_code8_cnt = ac_ptr0->bits[7];
99*437bfbebSnyanmisaka     reg->reg135.sw_ac1_code9_cnt = ac_ptr0->bits[8];
100*437bfbebSnyanmisaka     reg->reg135.sw_ac1_code10_cnt = ac_ptr0->bits[9];
101*437bfbebSnyanmisaka 
102*437bfbebSnyanmisaka     reg->reg136.sw_ac1_code11_cnt = ac_ptr0->bits[10];
103*437bfbebSnyanmisaka     reg->reg136.sw_ac1_code12_cnt = ac_ptr0->bits[11];
104*437bfbebSnyanmisaka     reg->reg136.sw_ac1_code13_cnt = ac_ptr0->bits[12];
105*437bfbebSnyanmisaka     reg->reg136.sw_ac1_code14_cnt = ac_ptr0->bits[13];
106*437bfbebSnyanmisaka 
107*437bfbebSnyanmisaka     reg->reg137.sw_ac1_code15_cnt = ac_ptr0->bits[14];
108*437bfbebSnyanmisaka     reg->reg137.sw_ac1_code16_cnt = ac_ptr0->bits[15];
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka     /* AC table 1 (the not-luma table) */
111*437bfbebSnyanmisaka     reg->reg137.sw_ac2_code1_cnt = ac_ptr1->bits[0];
112*437bfbebSnyanmisaka     reg->reg137.sw_ac2_code2_cnt = ac_ptr1->bits[1];
113*437bfbebSnyanmisaka     reg->reg137.sw_ac2_code3_cnt = ac_ptr1->bits[2];
114*437bfbebSnyanmisaka     reg->reg137.sw_ac2_code4_cnt = ac_ptr1->bits[3];
115*437bfbebSnyanmisaka 
116*437bfbebSnyanmisaka     reg->reg138.sw_ac2_code5_cnt = ac_ptr1->bits[4];
117*437bfbebSnyanmisaka     reg->reg138.sw_ac2_code6_cnt = ac_ptr1->bits[5];
118*437bfbebSnyanmisaka     reg->reg138.sw_ac2_code7_cnt = ac_ptr1->bits[6];
119*437bfbebSnyanmisaka     reg->reg138.sw_ac2_code8_cnt = ac_ptr1->bits[7];
120*437bfbebSnyanmisaka 
121*437bfbebSnyanmisaka     reg->reg139.sw_ac2_code9_cnt = ac_ptr1->bits[8];
122*437bfbebSnyanmisaka     reg->reg139.sw_ac2_code10_cnt = ac_ptr1->bits[9];
123*437bfbebSnyanmisaka     reg->reg139.sw_ac2_code11_cnt = ac_ptr1->bits[10];
124*437bfbebSnyanmisaka     reg->reg139.sw_ac2_code12_cnt = ac_ptr1->bits[11];
125*437bfbebSnyanmisaka 
126*437bfbebSnyanmisaka     reg->reg140.sw_ac2_code13_cnt = ac_ptr1->bits[12];
127*437bfbebSnyanmisaka     reg->reg140.sw_ac2_code14_cnt = ac_ptr1->bits[13];
128*437bfbebSnyanmisaka     reg->reg140.sw_ac2_code15_cnt = ac_ptr1->bits[14];
129*437bfbebSnyanmisaka     reg->reg140.sw_ac2_code16_cnt = ac_ptr1->bits[15];
130*437bfbebSnyanmisaka 
131*437bfbebSnyanmisaka     /* first, select the table we'll use.
132*437bfbebSnyanmisaka      * this trick is done because hardware always wants luma
133*437bfbebSnyanmisaka      * table as DC hardware table 0.
134*437bfbebSnyanmisaka      */
135*437bfbebSnyanmisaka     if (s->dc_index[0] == HUFFMAN_TABLE_ID_ZERO) {
136*437bfbebSnyanmisaka         /* Luma's DC uses Huffman table zero */
137*437bfbebSnyanmisaka         dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
138*437bfbebSnyanmisaka         dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
139*437bfbebSnyanmisaka     } else {
140*437bfbebSnyanmisaka         dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
141*437bfbebSnyanmisaka         dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
142*437bfbebSnyanmisaka     }
143*437bfbebSnyanmisaka 
144*437bfbebSnyanmisaka     /* write DC table 0 (luma) */
145*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code1_cnt = dc_ptr0->bits[0];
146*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code2_cnt = dc_ptr0->bits[1];
147*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code3_cnt = dc_ptr0->bits[2];
148*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code4_cnt = dc_ptr0->bits[3];
149*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code5_cnt = dc_ptr0->bits[4];
150*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code6_cnt = dc_ptr0->bits[5];
151*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code7_cnt = dc_ptr0->bits[6];
152*437bfbebSnyanmisaka     reg->reg141.sw_dc1_code8_cnt = dc_ptr0->bits[7];
153*437bfbebSnyanmisaka 
154*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code9_cnt = dc_ptr0->bits[8];
155*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code10_cnt = dc_ptr0->bits[9];
156*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code11_cnt = dc_ptr0->bits[10];
157*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code12_cnt = dc_ptr0->bits[11];
158*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code13_cnt = dc_ptr0->bits[12];
159*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code14_cnt = dc_ptr0->bits[13];
160*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code15_cnt = dc_ptr0->bits[14];
161*437bfbebSnyanmisaka     reg->reg142.sw_dc1_code16_cnt = dc_ptr0->bits[15];
162*437bfbebSnyanmisaka 
163*437bfbebSnyanmisaka     /* DC table 1 (the not-luma table) */
164*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code1_cnt = dc_ptr1->bits[0];
165*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code2_cnt = dc_ptr1->bits[1];
166*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code3_cnt = dc_ptr1->bits[2];
167*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code4_cnt = dc_ptr1->bits[3];
168*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code5_cnt = dc_ptr1->bits[4];
169*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code6_cnt = dc_ptr1->bits[5];
170*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code7_cnt = dc_ptr1->bits[6];
171*437bfbebSnyanmisaka     reg->reg143.sw_dc2_code8_cnt = dc_ptr1->bits[7];
172*437bfbebSnyanmisaka 
173*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code9_cnt = dc_ptr1->bits[8];
174*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code10_cnt = dc_ptr1->bits[9];
175*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code11_cnt = dc_ptr1->bits[10];
176*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code12_cnt = dc_ptr1->bits[11];
177*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code13_cnt = dc_ptr1->bits[12];
178*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code14_cnt = dc_ptr1->bits[13];
179*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code15_cnt = dc_ptr1->bits[14];
180*437bfbebSnyanmisaka     reg->reg144.sw_dc2_code16_cnt = dc_ptr1->bits[15];
181*437bfbebSnyanmisaka 
182*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
183*437bfbebSnyanmisaka     return;
184*437bfbebSnyanmisaka }
185*437bfbebSnyanmisaka 
186*437bfbebSnyanmisaka static void
jpegd_set_chroma_table_id(JpegdHalCtx * ctx,JpegdSyntax * syntax)187*437bfbebSnyanmisaka jpegd_set_chroma_table_id(JpegdHalCtx *ctx, JpegdSyntax *syntax)
188*437bfbebSnyanmisaka {
189*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
190*437bfbebSnyanmisaka     JpegdSyntax *s = syntax;
191*437bfbebSnyanmisaka     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
192*437bfbebSnyanmisaka     JpegRegSet *reg = &(info->regs);
193*437bfbebSnyanmisaka 
194*437bfbebSnyanmisaka     /* this trick is done because hardware always wants
195*437bfbebSnyanmisaka      * luma table as ac hardward table 0
196*437bfbebSnyanmisaka      */
197*437bfbebSnyanmisaka     if (s->ac_index[0] == HUFFMAN_TABLE_ID_ZERO) {
198*437bfbebSnyanmisaka         reg->reg122.sw_cb_ac_vlctable = s->ac_index[1];
199*437bfbebSnyanmisaka         reg->reg122.sw_cr_ac_vlctable = s->ac_index[2];
200*437bfbebSnyanmisaka     } else {
201*437bfbebSnyanmisaka         if (s->ac_index[0] == s->ac_index[1])
202*437bfbebSnyanmisaka             reg->reg122.sw_cb_ac_vlctable = 0;
203*437bfbebSnyanmisaka         else
204*437bfbebSnyanmisaka             reg->reg122.sw_cb_ac_vlctable = 1;
205*437bfbebSnyanmisaka 
206*437bfbebSnyanmisaka         if (s->ac_index[0] == s->ac_index[2])
207*437bfbebSnyanmisaka             reg->reg122.sw_cr_ac_vlctable = 0;
208*437bfbebSnyanmisaka         else
209*437bfbebSnyanmisaka             reg->reg122.sw_cr_ac_vlctable = 1;
210*437bfbebSnyanmisaka     }
211*437bfbebSnyanmisaka 
212*437bfbebSnyanmisaka     if (s->dc_index[0] == HUFFMAN_TABLE_ID_ZERO) {
213*437bfbebSnyanmisaka         reg->reg122.sw_cb_dc_vlctable = s->dc_index[1];
214*437bfbebSnyanmisaka         reg->reg122.sw_cr_dc_vlctable = s->dc_index[2];
215*437bfbebSnyanmisaka     } else {
216*437bfbebSnyanmisaka         if (s->dc_index[0] == s->dc_index[1])
217*437bfbebSnyanmisaka             reg->reg122.sw_cb_dc_vlctable = 0;
218*437bfbebSnyanmisaka         else
219*437bfbebSnyanmisaka             reg->reg122.sw_cb_dc_vlctable = 1;
220*437bfbebSnyanmisaka 
221*437bfbebSnyanmisaka         if (s->dc_index[0] == s->dc_index[2])
222*437bfbebSnyanmisaka             reg->reg122.sw_cr_dc_vlctable = 0;
223*437bfbebSnyanmisaka         else
224*437bfbebSnyanmisaka             reg->reg122.sw_cr_dc_vlctable = 1;
225*437bfbebSnyanmisaka     }
226*437bfbebSnyanmisaka 
227*437bfbebSnyanmisaka     reg->reg122.sw_cr_dc_vlctable3 = 0;
228*437bfbebSnyanmisaka     reg->reg122.sw_cb_dc_vlctable3 = 0;
229*437bfbebSnyanmisaka 
230*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
231*437bfbebSnyanmisaka     return;
232*437bfbebSnyanmisaka }
233*437bfbebSnyanmisaka 
234*437bfbebSnyanmisaka static void
jpegd_set_stream_offset(JpegdHalCtx * ctx,JpegdSyntax * syntax)235*437bfbebSnyanmisaka jpegd_set_stream_offset(JpegdHalCtx *ctx, JpegdSyntax *syntax)
236*437bfbebSnyanmisaka {
237*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
238*437bfbebSnyanmisaka     JpegdSyntax *s = syntax;
239*437bfbebSnyanmisaka 
240*437bfbebSnyanmisaka     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
241*437bfbebSnyanmisaka     JpegRegSet *reg = &(info->regs);
242*437bfbebSnyanmisaka     RK_U32 offset = 0, byte_cnt = 0;
243*437bfbebSnyanmisaka     RK_U32 bit_pos_in_byte = 0;
244*437bfbebSnyanmisaka     RK_U32 strm_len_by_hw = 0;
245*437bfbebSnyanmisaka     /* calculate and set stream start address to hw,
246*437bfbebSnyanmisaka      * the offset must be 8-byte aligned.
247*437bfbebSnyanmisaka      */
248*437bfbebSnyanmisaka     offset = (s->strm_offset & (~7));
249*437bfbebSnyanmisaka     reg->reg64_rlc_vlc_base = ctx->pkt_fd;
250*437bfbebSnyanmisaka     if (offset) {
251*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(ctx->dev, 64, offset);
252*437bfbebSnyanmisaka     }
253*437bfbebSnyanmisaka     /* calculate and set stream start bit to hardware
254*437bfbebSnyanmisaka      * change current pos to bus address style
255*437bfbebSnyanmisaka      * remove three lowest bits and add the difference to bitPosInWord
256*437bfbebSnyanmisaka      * used as bit pos in word not as bit pos in byte actually...
257*437bfbebSnyanmisaka      */
258*437bfbebSnyanmisaka     byte_cnt = ((uintptr_t) s->cur_pos & (7));
259*437bfbebSnyanmisaka     bit_pos_in_byte = byte_cnt * 8; /* 1 Byte = 8 bits */
260*437bfbebSnyanmisaka     reg->reg122.sw_strm_start_bit = bit_pos_in_byte;
261*437bfbebSnyanmisaka 
262*437bfbebSnyanmisaka     /* set up stream length for HW.
263*437bfbebSnyanmisaka      * length = size of original buffer - stream we already decoded in SW
264*437bfbebSnyanmisaka      */
265*437bfbebSnyanmisaka     strm_len_by_hw = s->pkt_len - offset;
266*437bfbebSnyanmisaka     reg->reg51_stream_info.sw_stream_len = strm_len_by_hw;
267*437bfbebSnyanmisaka     reg->reg122.sw_jpeg_stream_all = 1;
268*437bfbebSnyanmisaka 
269*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
270*437bfbebSnyanmisaka     return;
271*437bfbebSnyanmisaka }
272*437bfbebSnyanmisaka 
jpegd_setup_pp(JpegdHalCtx * ctx,JpegdSyntax * syntax)273*437bfbebSnyanmisaka static MPP_RET jpegd_setup_pp(JpegdHalCtx *ctx, JpegdSyntax *syntax)
274*437bfbebSnyanmisaka {
275*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
276*437bfbebSnyanmisaka     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
277*437bfbebSnyanmisaka     JpegRegSet *reg = &(info->regs);
278*437bfbebSnyanmisaka     JpegdSyntax *s = syntax;
279*437bfbebSnyanmisaka 
280*437bfbebSnyanmisaka     RK_U32 in_color = ctx->pp_info.pp_in_fmt;
281*437bfbebSnyanmisaka     RK_U32 out_color = ctx->pp_info.pp_out_fmt;
282*437bfbebSnyanmisaka     RK_U32 dither = ctx->pp_info.dither_enable;
283*437bfbebSnyanmisaka     RK_U32 crop_width = ctx->pp_info.crop_width;
284*437bfbebSnyanmisaka     RK_U32 crop_height = ctx->pp_info.crop_height;
285*437bfbebSnyanmisaka     RK_U32 crop_x = ctx->pp_info.crop_x;
286*437bfbebSnyanmisaka     RK_U32 crop_y = ctx->pp_info.crop_y;
287*437bfbebSnyanmisaka     RK_U32 in_width = s->hor_stride;
288*437bfbebSnyanmisaka     RK_U32 in_height = s->ver_stride;
289*437bfbebSnyanmisaka     RK_U32 out_width = s->hor_stride;
290*437bfbebSnyanmisaka     RK_U32 out_height = s->ver_stride;
291*437bfbebSnyanmisaka     RK_U32 uv_offset = s->hor_stride * s->ver_stride;
292*437bfbebSnyanmisaka 
293*437bfbebSnyanmisaka     reg->reg0.sw_pp_axi_rd_id = 0;
294*437bfbebSnyanmisaka     reg->reg0.sw_pp_axi_wr_id = 0;
295*437bfbebSnyanmisaka     reg->reg0.sw_pp_scmd_dis = 1;
296*437bfbebSnyanmisaka     reg->reg0.sw_pp_max_burst = 16;
297*437bfbebSnyanmisaka 
298*437bfbebSnyanmisaka     reg->reg18_pp_in_lu_base = 0;
299*437bfbebSnyanmisaka     reg->reg34.sw_ext_orig_width = in_width >> 4;
300*437bfbebSnyanmisaka 
301*437bfbebSnyanmisaka     reg->reg37.sw_pp_in_a2_endsel = 1;
302*437bfbebSnyanmisaka     reg->reg37.sw_pp_in_a1_swap32 = 1;
303*437bfbebSnyanmisaka     reg->reg37.sw_pp_in_a1_endian = 1;
304*437bfbebSnyanmisaka     reg->reg37.sw_pp_in_swap32_e = 1;
305*437bfbebSnyanmisaka     reg->reg37.sw_pp_in_endian = 1;
306*437bfbebSnyanmisaka     reg->reg37.sw_pp_out_endian = 1;
307*437bfbebSnyanmisaka     reg->reg37.sw_pp_out_swap32_e = 1;
308*437bfbebSnyanmisaka 
309*437bfbebSnyanmisaka     reg->reg41.sw_pp_clk_gate_e = 1;
310*437bfbebSnyanmisaka     reg->reg41.sw_pp_ahb_hlock_e = 1;
311*437bfbebSnyanmisaka     reg->reg41.sw_pp_data_disc_e = 1;
312*437bfbebSnyanmisaka 
313*437bfbebSnyanmisaka     if (crop_width <= 0) {
314*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_w_ext = (((in_width / 16) & 0xE00) >> 9);
315*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_width = ((in_width / 16) & 0x1FF);
316*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_h_ext = (((in_height / 16) & 0x700) >> 8);
317*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_height = ((in_height / 16) & 0x0FF);
318*437bfbebSnyanmisaka     } else {
319*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_w_ext = (((crop_width / 16) & 0xE00) >> 9);
320*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_width = ((crop_width / 16) & 0x1FF);
321*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_h_ext = (((crop_height / 16) & 0x700) >> 8);
322*437bfbebSnyanmisaka         reg->reg34.sw_pp_in_height = ((crop_height / 16) & 0x0FF);
323*437bfbebSnyanmisaka 
324*437bfbebSnyanmisaka         reg->reg14.sw_crop_startx_ext = (((crop_x / 16) & 0xE00) >> 9);
325*437bfbebSnyanmisaka         reg->reg14.sw_crop_startx = ((crop_x / 16) & 0x1FF);
326*437bfbebSnyanmisaka         reg->reg14.sw_crop_starty_ext = (((crop_y / 16) & 0x700) >> 8);
327*437bfbebSnyanmisaka         reg->reg14.sw_crop_starty = ((crop_y / 16) & 0x0FF);
328*437bfbebSnyanmisaka 
329*437bfbebSnyanmisaka         if (crop_width & 0x0F) {
330*437bfbebSnyanmisaka             reg->reg14.sw_pp_crop8_r_e = 1;
331*437bfbebSnyanmisaka         } else {
332*437bfbebSnyanmisaka             reg->reg14.sw_pp_crop8_r_e = 0;
333*437bfbebSnyanmisaka         }
334*437bfbebSnyanmisaka         if (crop_height & 0x0F) {
335*437bfbebSnyanmisaka             reg->reg14.sw_pp_crop8_d_e = 1;
336*437bfbebSnyanmisaka         } else {
337*437bfbebSnyanmisaka             reg->reg14.sw_pp_crop8_d_e = 0;
338*437bfbebSnyanmisaka         }
339*437bfbebSnyanmisaka         in_width = crop_width;
340*437bfbebSnyanmisaka         in_height = crop_height;
341*437bfbebSnyanmisaka     }
342*437bfbebSnyanmisaka 
343*437bfbebSnyanmisaka     reg->reg39.sw_display_width = out_width;
344*437bfbebSnyanmisaka     reg->reg35.sw_pp_out_width = out_width;
345*437bfbebSnyanmisaka     reg->reg35.sw_pp_out_height = out_height;
346*437bfbebSnyanmisaka 
347*437bfbebSnyanmisaka     switch (in_color) {
348*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV422INTERLAVE:
349*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV420SEMI:
350*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV420PLANAR:
351*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV400:
352*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV422SEMI:
353*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV420SEMITIELED:
354*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV440SEMI:
355*437bfbebSnyanmisaka         reg->reg38.sw_pp_in_format = in_color;
356*437bfbebSnyanmisaka         break;
357*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV444_SEMI:
358*437bfbebSnyanmisaka         reg->reg38.sw_pp_in_format = 7;
359*437bfbebSnyanmisaka         reg->reg38.sw_pp_in_format_es = 0;
360*437bfbebSnyanmisaka         break;
361*437bfbebSnyanmisaka     case    PP_IN_FORMAT_YUV411_SEMI:
362*437bfbebSnyanmisaka         reg->reg38.sw_pp_in_format = 0;
363*437bfbebSnyanmisaka         reg->reg38.sw_pp_in_format_es = 1;
364*437bfbebSnyanmisaka         break;
365*437bfbebSnyanmisaka     default:
366*437bfbebSnyanmisaka         mpp_err_f("unsupported format:%d", in_color);
367*437bfbebSnyanmisaka         return MPP_NOK;
368*437bfbebSnyanmisaka     }
369*437bfbebSnyanmisaka 
370*437bfbebSnyanmisaka     RK_U32 video_range = 1;
371*437bfbebSnyanmisaka 
372*437bfbebSnyanmisaka     reg->reg15.sw_rangemap_coef_y = 9;
373*437bfbebSnyanmisaka     reg->reg15.sw_rangemap_coef_c = 9;
374*437bfbebSnyanmisaka     reg->reg3.sw_pp_color_coefff = BRIGHTNESS;  /* brightness */
375*437bfbebSnyanmisaka 
376*437bfbebSnyanmisaka     if (out_color <= PP_OUT_FORMAT_ARGB) {
377*437bfbebSnyanmisaka         /*Bt.601*/
378*437bfbebSnyanmisaka         unsigned int    a = 298;
379*437bfbebSnyanmisaka         unsigned int    b = 409;
380*437bfbebSnyanmisaka         unsigned int    c = 208;
381*437bfbebSnyanmisaka         unsigned int    d = 100;
382*437bfbebSnyanmisaka         unsigned int    e = 516;
383*437bfbebSnyanmisaka 
384*437bfbebSnyanmisaka         /*Bt.709
385*437bfbebSnyanmisaka         unsigned int    a = 298;
386*437bfbebSnyanmisaka         unsigned int    b = 459;
387*437bfbebSnyanmisaka         unsigned int    c = 137;
388*437bfbebSnyanmisaka         unsigned int    d = 55;
389*437bfbebSnyanmisaka         unsigned int    e = 544;*/
390*437bfbebSnyanmisaka 
391*437bfbebSnyanmisaka         int satur = 0, tmp;
392*437bfbebSnyanmisaka         if (video_range != 0) {
393*437bfbebSnyanmisaka             /*Bt.601*/
394*437bfbebSnyanmisaka             a = 256;
395*437bfbebSnyanmisaka             b = 350;
396*437bfbebSnyanmisaka             c = 179;
397*437bfbebSnyanmisaka             d = 86;
398*437bfbebSnyanmisaka             e = 443;
399*437bfbebSnyanmisaka             /*Bt.709
400*437bfbebSnyanmisaka             a = 256;
401*437bfbebSnyanmisaka             b = 403;
402*437bfbebSnyanmisaka             c = 120;
403*437bfbebSnyanmisaka             d = 48;
404*437bfbebSnyanmisaka             e = 475;*/
405*437bfbebSnyanmisaka 
406*437bfbebSnyanmisaka             reg->reg15.sw_ycbcr_range = video_range;
407*437bfbebSnyanmisaka         }
408*437bfbebSnyanmisaka         int contrast = CONTRAST;
409*437bfbebSnyanmisaka         if (contrast != 0) {
410*437bfbebSnyanmisaka             int thr1y, thr2y, off1, off2, thr1, thr2, a1, a2;
411*437bfbebSnyanmisaka             if (video_range == 0) {
412*437bfbebSnyanmisaka                 int tmp1, tmp2;
413*437bfbebSnyanmisaka                 /* Contrast */
414*437bfbebSnyanmisaka                 thr1 = (219 * (contrast + 128)) / 512;
415*437bfbebSnyanmisaka                 thr1y = (219 - 2 * thr1) / 2;
416*437bfbebSnyanmisaka                 thr2 = 219 - thr1;
417*437bfbebSnyanmisaka                 thr2y = 219 - thr1y;
418*437bfbebSnyanmisaka 
419*437bfbebSnyanmisaka                 tmp1 = (thr1y * 256) / thr1;
420*437bfbebSnyanmisaka                 tmp2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
421*437bfbebSnyanmisaka                 off1 = ((thr1y - ((tmp2 * thr1) / 256)) * a) / 256;
422*437bfbebSnyanmisaka                 off2 = ((thr2y - ((tmp1 * thr2) / 256)) * a) / 256;
423*437bfbebSnyanmisaka 
424*437bfbebSnyanmisaka                 tmp1 = (64 * (contrast + 128)) / 128;
425*437bfbebSnyanmisaka                 tmp2 = 256 * (128 - tmp1);
426*437bfbebSnyanmisaka                 a1 = (tmp2 + off2) / thr1;
427*437bfbebSnyanmisaka                 a2 = a1 + (256 * (off2 - 1)) / (thr2 - thr1);
428*437bfbebSnyanmisaka             } else {
429*437bfbebSnyanmisaka                 /* Contrast */
430*437bfbebSnyanmisaka                 thr1 = (64 * (contrast + 128)) / 128;
431*437bfbebSnyanmisaka                 thr1y = 128 - thr1;
432*437bfbebSnyanmisaka                 thr2 = 256 - thr1;
433*437bfbebSnyanmisaka                 thr2y = 256 - thr1y;
434*437bfbebSnyanmisaka                 a1 = (thr1y * 256) / thr1;
435*437bfbebSnyanmisaka                 a2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
436*437bfbebSnyanmisaka                 off1 = thr1y - (a2 * thr1) / 256;
437*437bfbebSnyanmisaka                 off2 = thr2y - (a1 * thr2) / 256;
438*437bfbebSnyanmisaka             }
439*437bfbebSnyanmisaka 
440*437bfbebSnyanmisaka             if (a1 > 1023)
441*437bfbebSnyanmisaka                 a1 = 1023;
442*437bfbebSnyanmisaka             else if (a1 < 0)
443*437bfbebSnyanmisaka                 a1 = 0;
444*437bfbebSnyanmisaka 
445*437bfbebSnyanmisaka             if (a2 > 1023)
446*437bfbebSnyanmisaka                 a2 = 1023;
447*437bfbebSnyanmisaka             else if (a2 < 0)
448*437bfbebSnyanmisaka                 a2 = 0;
449*437bfbebSnyanmisaka 
450*437bfbebSnyanmisaka             if (thr1 > 255)
451*437bfbebSnyanmisaka                 thr1 = 255;
452*437bfbebSnyanmisaka             else if (thr1 < 0)
453*437bfbebSnyanmisaka                 thr1 = 0;
454*437bfbebSnyanmisaka 
455*437bfbebSnyanmisaka             if (thr2 > 255)
456*437bfbebSnyanmisaka                 thr2 = 255;
457*437bfbebSnyanmisaka             else if (thr2 < 0)
458*437bfbebSnyanmisaka                 thr2 = 0;
459*437bfbebSnyanmisaka 
460*437bfbebSnyanmisaka             if (off1 > 511)
461*437bfbebSnyanmisaka                 off1 = 511;
462*437bfbebSnyanmisaka             else if (off1 < -512)
463*437bfbebSnyanmisaka                 off1 = -512;
464*437bfbebSnyanmisaka 
465*437bfbebSnyanmisaka             if (off2 > 511)
466*437bfbebSnyanmisaka                 off2 = 511;
467*437bfbebSnyanmisaka             else if (off2 < -512)
468*437bfbebSnyanmisaka                 off2 = -512;
469*437bfbebSnyanmisaka 
470*437bfbebSnyanmisaka             reg->reg31.sw_contrast_thr1 = thr1;
471*437bfbebSnyanmisaka             reg->reg31.sw_contrast_thr2 = thr2;
472*437bfbebSnyanmisaka             reg->reg32.sw_contrast_off1 = off1;
473*437bfbebSnyanmisaka             reg->reg32.sw_contrast_off2 = off2;
474*437bfbebSnyanmisaka 
475*437bfbebSnyanmisaka             reg->reg1.sw_color_coeffa1 = a1;
476*437bfbebSnyanmisaka             reg->reg1.sw_color_coeffa2 = a2;
477*437bfbebSnyanmisaka         } else {
478*437bfbebSnyanmisaka             reg->reg31.sw_contrast_thr1 = 55;
479*437bfbebSnyanmisaka             reg->reg31.sw_contrast_thr2 = 165;
480*437bfbebSnyanmisaka             reg->reg32.sw_contrast_off1 = 0;
481*437bfbebSnyanmisaka             reg->reg32.sw_contrast_off2 = 0;
482*437bfbebSnyanmisaka 
483*437bfbebSnyanmisaka             tmp = a;
484*437bfbebSnyanmisaka             if (tmp > 1023)
485*437bfbebSnyanmisaka                 tmp = 1023;
486*437bfbebSnyanmisaka             else if (tmp < 0)
487*437bfbebSnyanmisaka                 tmp = 0;
488*437bfbebSnyanmisaka 
489*437bfbebSnyanmisaka             reg->reg1.sw_color_coeffa1 = tmp;
490*437bfbebSnyanmisaka             reg->reg1.sw_color_coeffa2 = tmp;
491*437bfbebSnyanmisaka         }
492*437bfbebSnyanmisaka 
493*437bfbebSnyanmisaka         reg->reg37.sw_pp_out_endian = 0;
494*437bfbebSnyanmisaka 
495*437bfbebSnyanmisaka         satur = 64 + SATURATION; /* saturation */
496*437bfbebSnyanmisaka         tmp = (satur * (int) b) / 64;
497*437bfbebSnyanmisaka         if (tmp > 1023)
498*437bfbebSnyanmisaka             tmp = 1023;
499*437bfbebSnyanmisaka         else if (tmp < 0)
500*437bfbebSnyanmisaka             tmp = 0;
501*437bfbebSnyanmisaka         reg->reg1.sw_color_coeffb = (unsigned int) tmp;
502*437bfbebSnyanmisaka 
503*437bfbebSnyanmisaka         tmp = (satur * (int) c) / 64;
504*437bfbebSnyanmisaka         if (tmp > 1023)
505*437bfbebSnyanmisaka             tmp = 1023;
506*437bfbebSnyanmisaka         else if (tmp < 0)
507*437bfbebSnyanmisaka             tmp = 0;
508*437bfbebSnyanmisaka         reg->reg2.sw_color_coeffc = (unsigned int) tmp;
509*437bfbebSnyanmisaka 
510*437bfbebSnyanmisaka         tmp = (satur * (int) d) / 64;
511*437bfbebSnyanmisaka         if (tmp > 1023)
512*437bfbebSnyanmisaka             tmp = 1023;
513*437bfbebSnyanmisaka         else if (tmp < 0)
514*437bfbebSnyanmisaka             tmp = 0;
515*437bfbebSnyanmisaka         reg->reg2.sw_color_coeffd = (unsigned int) tmp;
516*437bfbebSnyanmisaka 
517*437bfbebSnyanmisaka         tmp = (satur * (int) e) / 64;
518*437bfbebSnyanmisaka         if (tmp > 1023)
519*437bfbebSnyanmisaka             tmp = 1023;
520*437bfbebSnyanmisaka         else if (tmp < 0)
521*437bfbebSnyanmisaka             tmp = 0;
522*437bfbebSnyanmisaka         reg->reg2.sw_color_coeffe = (unsigned int) tmp;
523*437bfbebSnyanmisaka     }
524*437bfbebSnyanmisaka 
525*437bfbebSnyanmisaka     if (out_color <= PP_OUT_FORMAT_ARGB) {
526*437bfbebSnyanmisaka         PpRgbCfg *cfg = get_pp_rgb_Cfg(ctx->output_fmt);
527*437bfbebSnyanmisaka         reg->reg9_r_mask = cfg->r_mask;
528*437bfbebSnyanmisaka         reg->reg10_g_mask = cfg->g_mask;
529*437bfbebSnyanmisaka         reg->reg11_b_mask = cfg->b_mask;
530*437bfbebSnyanmisaka         reg->reg16.sw_rgb_r_padd = cfg->r_padd;
531*437bfbebSnyanmisaka         reg->reg16.sw_rgb_g_padd = cfg->g_padd;
532*437bfbebSnyanmisaka         reg->reg16.sw_rgb_b_padd = cfg->b_padd;
533*437bfbebSnyanmisaka 
534*437bfbebSnyanmisaka         if (dither) {
535*437bfbebSnyanmisaka             jpegd_dbg_hal("we do dither.");
536*437bfbebSnyanmisaka             reg->reg36.sw_dither_select_r = cfg->r_dither;
537*437bfbebSnyanmisaka             reg->reg36.sw_dither_select_g = cfg->g_dither;
538*437bfbebSnyanmisaka             reg->reg36.sw_dither_select_b = cfg->b_dither;
539*437bfbebSnyanmisaka         } else {
540*437bfbebSnyanmisaka             jpegd_dbg_hal("we do not dither.");
541*437bfbebSnyanmisaka         }
542*437bfbebSnyanmisaka 
543*437bfbebSnyanmisaka         reg->reg37.sw_rgb_pix_in32 = cfg->rgb_in_32;
544*437bfbebSnyanmisaka         reg->reg37.sw_pp_out_swap16_e = cfg->swap_16;
545*437bfbebSnyanmisaka         reg->reg37.sw_pp_out_swap32_e = cfg->swap_32;
546*437bfbebSnyanmisaka         reg->reg37.sw_pp_out_endian = cfg->out_endian;
547*437bfbebSnyanmisaka 
548*437bfbebSnyanmisaka         reg->reg38.sw_pp_out_format = 0;
549*437bfbebSnyanmisaka 
550*437bfbebSnyanmisaka     } else if (out_color == PP_OUT_FORMAT_YUV422INTERLAVE) {
551*437bfbebSnyanmisaka         reg->reg38.sw_pp_out_format = 3;
552*437bfbebSnyanmisaka     } else if (out_color == PP_OUT_FORMAT_YUV420INTERLAVE) {
553*437bfbebSnyanmisaka         reg->reg38.sw_pp_out_format = 5;
554*437bfbebSnyanmisaka     } else {
555*437bfbebSnyanmisaka         mpp_err_f("unsuppotred format:%d", out_color);
556*437bfbebSnyanmisaka         return -1;
557*437bfbebSnyanmisaka     }
558*437bfbebSnyanmisaka 
559*437bfbebSnyanmisaka     reg->reg38.sw_rotation_mode = 0;
560*437bfbebSnyanmisaka 
561*437bfbebSnyanmisaka     unsigned int inw, inh;
562*437bfbebSnyanmisaka     unsigned int outw, outh;
563*437bfbebSnyanmisaka 
564*437bfbebSnyanmisaka     inw = in_width - 1;
565*437bfbebSnyanmisaka     inh = in_height - 1;
566*437bfbebSnyanmisaka     outw = out_width - 1;
567*437bfbebSnyanmisaka     outh = out_height - 1;
568*437bfbebSnyanmisaka 
569*437bfbebSnyanmisaka     if (inw < outw) {
570*437bfbebSnyanmisaka         reg->reg4.sw_hor_scale_mode = 1;
571*437bfbebSnyanmisaka         reg->reg4.sw_scale_wratio = (outw << 16) / inw;
572*437bfbebSnyanmisaka         reg->reg6.sw_wscale_invra = (inw << 16) / outw;
573*437bfbebSnyanmisaka     } else if (inw > outw) {
574*437bfbebSnyanmisaka         reg->reg4.sw_hor_scale_mode = 2;
575*437bfbebSnyanmisaka         reg->reg6.sw_wscale_invra = ((outw + 1) << 16) / (inw + 1);
576*437bfbebSnyanmisaka     } else
577*437bfbebSnyanmisaka         reg->reg4.sw_hor_scale_mode = 0;
578*437bfbebSnyanmisaka 
579*437bfbebSnyanmisaka     if (inh < outh) {
580*437bfbebSnyanmisaka         reg->reg4.sw_ver_scale_mode = 1;
581*437bfbebSnyanmisaka         reg->reg5.sw_scale_hratio = (outh << 16) / inh;
582*437bfbebSnyanmisaka         reg->reg6.sw_hscale_invra = (inh << 16) / outh;
583*437bfbebSnyanmisaka     } else if (inh > outh) {
584*437bfbebSnyanmisaka         reg->reg4.sw_ver_scale_mode = 2;
585*437bfbebSnyanmisaka         reg->reg6.sw_hscale_invra = ((outh + 1) << 16) / (inh + 1) + 1;
586*437bfbebSnyanmisaka     } else
587*437bfbebSnyanmisaka         reg->reg4.sw_ver_scale_mode = 0;
588*437bfbebSnyanmisaka 
589*437bfbebSnyanmisaka     reg->reg41.sw_pp_pipeline_e = ctx->pp_info.pp_enable;
590*437bfbebSnyanmisaka 
591*437bfbebSnyanmisaka     jpegd_dbg_hal("pp_enable %d\n", ctx->pp_info.pp_enable);
592*437bfbebSnyanmisaka 
593*437bfbebSnyanmisaka     if (ctx->pp_info.pp_enable) {
594*437bfbebSnyanmisaka         reg->reg41.sw_pp_pipeline_e = 1;
595*437bfbebSnyanmisaka         reg->reg57_enable_ctrl.sw_dec_out_dis = 1;
596*437bfbebSnyanmisaka 
597*437bfbebSnyanmisaka         reg->reg63_dec_out_base = 0;
598*437bfbebSnyanmisaka         reg->reg131_jpg_ch_out_base = 0;
599*437bfbebSnyanmisaka 
600*437bfbebSnyanmisaka         reg->reg21_pp_out_lu_base = ctx->frame_fd;
601*437bfbebSnyanmisaka         reg->reg22_pp_out_ch_base = ctx->frame_fd;
602*437bfbebSnyanmisaka 
603*437bfbebSnyanmisaka         if (uv_offset)
604*437bfbebSnyanmisaka             mpp_dev_set_reg_offset(ctx->dev, 22, uv_offset);
605*437bfbebSnyanmisaka 
606*437bfbebSnyanmisaka         jpegd_dbg_hal("output_frame_fd:%x, reg22:%x", ctx->frame_fd,
607*437bfbebSnyanmisaka                       reg->reg22_pp_out_ch_base);
608*437bfbebSnyanmisaka     } else {
609*437bfbebSnyanmisaka         // output without pp
610*437bfbebSnyanmisaka         reg->reg41.sw_pp_pipeline_e = 0;
611*437bfbebSnyanmisaka         reg->reg57_enable_ctrl.sw_dec_out_dis = 0;
612*437bfbebSnyanmisaka 
613*437bfbebSnyanmisaka         reg->reg21_pp_out_lu_base = 0;
614*437bfbebSnyanmisaka         reg->reg22_pp_out_ch_base = 0;
615*437bfbebSnyanmisaka 
616*437bfbebSnyanmisaka         reg->reg63_dec_out_base = ctx->frame_fd;
617*437bfbebSnyanmisaka         reg->reg131_jpg_ch_out_base = ctx->frame_fd;
618*437bfbebSnyanmisaka 
619*437bfbebSnyanmisaka         if (uv_offset)
620*437bfbebSnyanmisaka             mpp_dev_set_reg_offset(ctx->dev, 131, uv_offset);
621*437bfbebSnyanmisaka 
622*437bfbebSnyanmisaka         jpegd_dbg_hal("output_frame_fd:%x, reg131:%x", ctx->frame_fd,
623*437bfbebSnyanmisaka                       reg->reg131_jpg_ch_out_base);
624*437bfbebSnyanmisaka     }
625*437bfbebSnyanmisaka 
626*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
627*437bfbebSnyanmisaka     return MPP_OK;
628*437bfbebSnyanmisaka }
629*437bfbebSnyanmisaka 
630*437bfbebSnyanmisaka static
jpegd_gen_regs(JpegdHalCtx * ctx,JpegdSyntax * syntax)631*437bfbebSnyanmisaka MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
632*437bfbebSnyanmisaka {
633*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
634*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
635*437bfbebSnyanmisaka     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
636*437bfbebSnyanmisaka     JpegRegSet *reg = &(info->regs);
637*437bfbebSnyanmisaka     JpegdSyntax *s = syntax;
638*437bfbebSnyanmisaka 
639*437bfbebSnyanmisaka     jpegd_regs_init(reg);
640*437bfbebSnyanmisaka 
641*437bfbebSnyanmisaka     reg->reg50_dec_ctrl.sw_filtering_dis = 1;
642*437bfbebSnyanmisaka     reg->reg53_dec_mode = DEC_MODE_JPEG;
643*437bfbebSnyanmisaka 
644*437bfbebSnyanmisaka     reg->reg57_enable_ctrl.sw_dec_e = 1;  /* Enable jpeg mode */
645*437bfbebSnyanmisaka     reg->reg57_enable_ctrl.sw_pjpeg_e = 0;
646*437bfbebSnyanmisaka     reg->reg57_enable_ctrl.sw_dec_out_dis = 0;
647*437bfbebSnyanmisaka     reg->reg57_enable_ctrl.sw_rlc_mode_e = 0;
648*437bfbebSnyanmisaka 
649*437bfbebSnyanmisaka     /* frame size, round up the number of mbs */
650*437bfbebSnyanmisaka     reg->reg120.sw_pic_mb_h_ext = ((((s->ver_stride) >> (4)) & 0x700) >> 8);
651*437bfbebSnyanmisaka     reg->reg120.sw_pic_mb_w_ext = ((((s->hor_stride) >> (4)) & 0xE00) >> 9);
652*437bfbebSnyanmisaka     reg->reg120.sw_pic_mb_width = ((s->hor_stride) >> (4)) & 0x1FF;
653*437bfbebSnyanmisaka     reg->reg120.sw_pic_mb_hight_p = ((s->ver_stride) >> (4)) & 0x0FF;
654*437bfbebSnyanmisaka 
655*437bfbebSnyanmisaka     reg->reg121.sw_pjpeg_fildown_e = s->fill_bottom;
656*437bfbebSnyanmisaka     /* Set spectral selection start coefficient */
657*437bfbebSnyanmisaka     reg->reg121.sw_pjpeg_ss = s->scan_start;
658*437bfbebSnyanmisaka     /* Set spectral selection end coefficient */
659*437bfbebSnyanmisaka     reg->reg121.sw_pjpeg_se = s->scan_end;
660*437bfbebSnyanmisaka     /* Set the point transform used in the preceding scan */
661*437bfbebSnyanmisaka     reg->reg121.sw_pjpeg_ah = s->prev_shift;
662*437bfbebSnyanmisaka     /* Set the point transform value */
663*437bfbebSnyanmisaka     reg->reg121.sw_pjpeg_al = s->point_transform;
664*437bfbebSnyanmisaka 
665*437bfbebSnyanmisaka     reg->reg122.sw_jpeg_qtables = s->qtable_cnt;
666*437bfbebSnyanmisaka     reg->reg122.sw_jpeg_mode = s->yuv_mode;
667*437bfbebSnyanmisaka     reg->reg122.sw_jpeg_filright_e = s->fill_right;
668*437bfbebSnyanmisaka 
669*437bfbebSnyanmisaka     reg->reg148.sw_slice_h = 0;
670*437bfbebSnyanmisaka     /* Set bit 21 of reg148 to 1, notifying hardware to decode jpeg
671*437bfbebSnyanmisaka      * including DRI segment
672*437bfbebSnyanmisaka      */
673*437bfbebSnyanmisaka     reg->reg148.sw_syn_marker_e = 1;
674*437bfbebSnyanmisaka 
675*437bfbebSnyanmisaka     /* tell hardware that height is 8-pixel aligned,
676*437bfbebSnyanmisaka      * but not 16-pixel aligned
677*437bfbebSnyanmisaka      */
678*437bfbebSnyanmisaka     if ((s->height % 16) && ((s->height % 16) <= 8) &&
679*437bfbebSnyanmisaka         (!ctx->pp_info.pp_enable) &&
680*437bfbebSnyanmisaka         (s->yuv_mode == JPEGDEC_YUV422 ||
681*437bfbebSnyanmisaka          s->yuv_mode == JPEGDEC_YUV444 ||
682*437bfbebSnyanmisaka          s->yuv_mode == JPEGDEC_YUV411)) {
683*437bfbebSnyanmisaka         reg->reg148.sw_jpeg_height8_flag = 1;
684*437bfbebSnyanmisaka     }
685*437bfbebSnyanmisaka 
686*437bfbebSnyanmisaka     /* write VLC code word number to register */
687*437bfbebSnyanmisaka     jpegd_write_code_word_number(ctx, s);
688*437bfbebSnyanmisaka 
689*437bfbebSnyanmisaka     /* Create AC/DC/QP tables for hardware */
690*437bfbebSnyanmisaka     jpegd_write_qp_ac_dc_table(ctx, s);
691*437bfbebSnyanmisaka 
692*437bfbebSnyanmisaka     /* Select which tables the chromas use */
693*437bfbebSnyanmisaka     jpegd_set_chroma_table_id(ctx, s);
694*437bfbebSnyanmisaka 
695*437bfbebSnyanmisaka     /* write table base */
696*437bfbebSnyanmisaka     reg->reg61_qtable_base = mpp_buffer_get_fd(ctx->pTableBase);
697*437bfbebSnyanmisaka     if (reg->reg61_qtable_base <= 0) {
698*437bfbebSnyanmisaka         mpp_err_f("get qtable_base failed\n");
699*437bfbebSnyanmisaka         return MPP_NOK;
700*437bfbebSnyanmisaka     }
701*437bfbebSnyanmisaka     /* set up stream position for HW decode */
702*437bfbebSnyanmisaka     jpegd_set_stream_offset(ctx, s);
703*437bfbebSnyanmisaka 
704*437bfbebSnyanmisaka     /* set restart interval */
705*437bfbebSnyanmisaka     if (s->restart_interval) {
706*437bfbebSnyanmisaka         reg->reg122.sw_sync_marker_e = 1;
707*437bfbebSnyanmisaka         /* If exists DRI segment, bit 0 to bit 15 of reg123 is set
708*437bfbebSnyanmisaka          * to restart interval */
709*437bfbebSnyanmisaka         reg->reg123.sw_pjpeg_rest_freq = s->restart_interval;
710*437bfbebSnyanmisaka     } else {
711*437bfbebSnyanmisaka         reg->reg122.sw_sync_marker_e = 0;
712*437bfbebSnyanmisaka     }
713*437bfbebSnyanmisaka 
714*437bfbebSnyanmisaka     jpegd_setup_pp(ctx, syntax);
715*437bfbebSnyanmisaka 
716*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
717*437bfbebSnyanmisaka     return ret;
718*437bfbebSnyanmisaka }
719*437bfbebSnyanmisaka 
hal_jpegd_vdpu2_init(void * hal,MppHalCfg * cfg)720*437bfbebSnyanmisaka MPP_RET hal_jpegd_vdpu2_init(void *hal, MppHalCfg *cfg)
721*437bfbebSnyanmisaka {
722*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
723*437bfbebSnyanmisaka     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
724*437bfbebSnyanmisaka 
725*437bfbebSnyanmisaka     mpp_assert(JpegHalCtx);
726*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
727*437bfbebSnyanmisaka 
728*437bfbebSnyanmisaka     //configure
729*437bfbebSnyanmisaka     JpegHalCtx->dec_cb       = cfg->dec_cb;
730*437bfbebSnyanmisaka     JpegHalCtx->packet_slots = cfg->packet_slots;
731*437bfbebSnyanmisaka     JpegHalCtx->frame_slots  = cfg->frame_slots;
732*437bfbebSnyanmisaka     JpegHalCtx->have_pp      = cfg->hw_info->cap_jpg_pp_out;
733*437bfbebSnyanmisaka 
734*437bfbebSnyanmisaka     //init regs
735*437bfbebSnyanmisaka     JpegdIocRegInfo *info = NULL;
736*437bfbebSnyanmisaka     info = mpp_calloc(JpegdIocRegInfo, 1);
737*437bfbebSnyanmisaka     if (info == NULL) {
738*437bfbebSnyanmisaka         mpp_err_f("allocate jpegd ioctl info failed\n");
739*437bfbebSnyanmisaka         return MPP_ERR_NOMEM;
740*437bfbebSnyanmisaka     }
741*437bfbebSnyanmisaka     memset(info, 0, sizeof(JpegdIocRegInfo));
742*437bfbebSnyanmisaka     JpegHalCtx->regs = (void *)info;
743*437bfbebSnyanmisaka 
744*437bfbebSnyanmisaka     //malloc hw buf
745*437bfbebSnyanmisaka     if (JpegHalCtx->group == NULL) {
746*437bfbebSnyanmisaka         ret = mpp_buffer_group_get_internal(&JpegHalCtx->group,
747*437bfbebSnyanmisaka                                             MPP_BUFFER_TYPE_ION);
748*437bfbebSnyanmisaka         if (ret) {
749*437bfbebSnyanmisaka             mpp_err_f("mpp_buffer_group_get failed\n");
750*437bfbebSnyanmisaka             return ret;
751*437bfbebSnyanmisaka         }
752*437bfbebSnyanmisaka     }
753*437bfbebSnyanmisaka 
754*437bfbebSnyanmisaka     ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->pTableBase,
755*437bfbebSnyanmisaka                          JPEGD_BASELINE_TABLE_SIZE);
756*437bfbebSnyanmisaka     if (ret) {
757*437bfbebSnyanmisaka         mpp_err_f("get buffer failed\n");
758*437bfbebSnyanmisaka         return ret;
759*437bfbebSnyanmisaka     }
760*437bfbebSnyanmisaka 
761*437bfbebSnyanmisaka     PPInfo *pp_info = &(JpegHalCtx->pp_info);
762*437bfbebSnyanmisaka     memset(pp_info, 0, sizeof(PPInfo));
763*437bfbebSnyanmisaka     pp_info->pp_enable = 0;
764*437bfbebSnyanmisaka     pp_info->pp_in_fmt = PP_IN_FORMAT_YUV420SEMI;
765*437bfbebSnyanmisaka     pp_info->pp_out_fmt = PP_OUT_FORMAT_YUV420INTERLAVE;
766*437bfbebSnyanmisaka 
767*437bfbebSnyanmisaka     JpegHalCtx->output_fmt = MPP_FMT_YUV420SP;
768*437bfbebSnyanmisaka     JpegHalCtx->set_output_fmt_flag = 0;
769*437bfbebSnyanmisaka 
770*437bfbebSnyanmisaka     //init dbg stuff
771*437bfbebSnyanmisaka     JpegHalCtx->hal_debug_enable = 0;
772*437bfbebSnyanmisaka     JpegHalCtx->frame_count = 0;
773*437bfbebSnyanmisaka     JpegHalCtx->output_yuv_count = 0;
774*437bfbebSnyanmisaka 
775*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
776*437bfbebSnyanmisaka     return MPP_OK;
777*437bfbebSnyanmisaka }
778*437bfbebSnyanmisaka 
hal_jpegd_vdpu2_deinit(void * hal)779*437bfbebSnyanmisaka MPP_RET hal_jpegd_vdpu2_deinit(void *hal)
780*437bfbebSnyanmisaka {
781*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
782*437bfbebSnyanmisaka     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
783*437bfbebSnyanmisaka 
784*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
785*437bfbebSnyanmisaka 
786*437bfbebSnyanmisaka     if (JpegHalCtx->dev) {
787*437bfbebSnyanmisaka         mpp_dev_deinit(JpegHalCtx->dev);
788*437bfbebSnyanmisaka         JpegHalCtx->dev = NULL;
789*437bfbebSnyanmisaka     }
790*437bfbebSnyanmisaka 
791*437bfbebSnyanmisaka     if (JpegHalCtx->pTableBase) {
792*437bfbebSnyanmisaka         ret = mpp_buffer_put(JpegHalCtx->pTableBase);
793*437bfbebSnyanmisaka         if (ret) {
794*437bfbebSnyanmisaka             mpp_err_f("put table buffer failed\n");
795*437bfbebSnyanmisaka             return ret;
796*437bfbebSnyanmisaka         }
797*437bfbebSnyanmisaka     }
798*437bfbebSnyanmisaka 
799*437bfbebSnyanmisaka     if (JpegHalCtx->group) {
800*437bfbebSnyanmisaka         ret = mpp_buffer_group_put(JpegHalCtx->group);
801*437bfbebSnyanmisaka         if (ret) {
802*437bfbebSnyanmisaka             mpp_err_f("group free buffer failed\n");
803*437bfbebSnyanmisaka             return ret;
804*437bfbebSnyanmisaka         }
805*437bfbebSnyanmisaka     }
806*437bfbebSnyanmisaka 
807*437bfbebSnyanmisaka     if (JpegHalCtx->regs) {
808*437bfbebSnyanmisaka         mpp_free(JpegHalCtx->regs);
809*437bfbebSnyanmisaka         JpegHalCtx->regs = NULL;
810*437bfbebSnyanmisaka     }
811*437bfbebSnyanmisaka 
812*437bfbebSnyanmisaka     JpegHalCtx->set_output_fmt_flag = 0;
813*437bfbebSnyanmisaka     JpegHalCtx->hal_debug_enable = 0;
814*437bfbebSnyanmisaka     JpegHalCtx->frame_count = 0;
815*437bfbebSnyanmisaka     JpegHalCtx->output_yuv_count = 0;
816*437bfbebSnyanmisaka 
817*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
818*437bfbebSnyanmisaka     return MPP_OK;
819*437bfbebSnyanmisaka }
820*437bfbebSnyanmisaka 
hal_jpegd_vdpu2_gen_regs(void * hal,HalTaskInfo * syn)821*437bfbebSnyanmisaka MPP_RET hal_jpegd_vdpu2_gen_regs(void *hal,  HalTaskInfo *syn)
822*437bfbebSnyanmisaka {
823*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
824*437bfbebSnyanmisaka     if (NULL == hal || NULL == syn) {
825*437bfbebSnyanmisaka         mpp_err_f("NULL pointer");
826*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
827*437bfbebSnyanmisaka     }
828*437bfbebSnyanmisaka 
829*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
830*437bfbebSnyanmisaka     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
831*437bfbebSnyanmisaka     JpegdSyntax *syntax = (JpegdSyntax *)syn->dec.syntax.data;
832*437bfbebSnyanmisaka     MppBuffer streambuf = NULL;
833*437bfbebSnyanmisaka     MppBuffer outputBuf = NULL;
834*437bfbebSnyanmisaka 
835*437bfbebSnyanmisaka     if (syn->dec.flags.parse_err)
836*437bfbebSnyanmisaka         goto RET;
837*437bfbebSnyanmisaka 
838*437bfbebSnyanmisaka     ret = jpeg_image_check_size(syntax->hor_stride, syntax->ver_stride);
839*437bfbebSnyanmisaka     if (ret)
840*437bfbebSnyanmisaka         goto RET;
841*437bfbebSnyanmisaka 
842*437bfbebSnyanmisaka     if (syn->dec.valid) {
843*437bfbebSnyanmisaka         ret = jpegd_setup_output_fmt(JpegHalCtx, syntax, syn->dec.output);
844*437bfbebSnyanmisaka         if (ret) {
845*437bfbebSnyanmisaka             mpp_err_f("setup output format %x failed\n", syntax->output_fmt);
846*437bfbebSnyanmisaka             goto RET;
847*437bfbebSnyanmisaka         }
848*437bfbebSnyanmisaka 
849*437bfbebSnyanmisaka         /* input stream address */
850*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(JpegHalCtx->packet_slots, syn->dec.input,
851*437bfbebSnyanmisaka                               SLOT_BUFFER, &streambuf);
852*437bfbebSnyanmisaka         JpegHalCtx->pkt_fd = mpp_buffer_get_fd(streambuf);
853*437bfbebSnyanmisaka         if (JpegHalCtx->pkt_fd <= 0) {
854*437bfbebSnyanmisaka             mpp_err_f("get pkt_fd failed\n");
855*437bfbebSnyanmisaka             goto RET;
856*437bfbebSnyanmisaka         }
857*437bfbebSnyanmisaka         syntax->pkt_len = jpegd_vdpu_tail_0xFF_patch(streambuf, syntax->pkt_len);
858*437bfbebSnyanmisaka 
859*437bfbebSnyanmisaka         /* output picture address */
860*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, syn->dec.output,
861*437bfbebSnyanmisaka                               SLOT_BUFFER, &outputBuf);
862*437bfbebSnyanmisaka         JpegHalCtx->frame_fd = mpp_buffer_get_fd(outputBuf);
863*437bfbebSnyanmisaka         if (JpegHalCtx->frame_fd <= 0) {
864*437bfbebSnyanmisaka             mpp_err_f("get frame_fd failed\n");
865*437bfbebSnyanmisaka             goto RET;
866*437bfbebSnyanmisaka         }
867*437bfbebSnyanmisaka 
868*437bfbebSnyanmisaka         ret = jpegd_gen_regs(JpegHalCtx, syntax);
869*437bfbebSnyanmisaka         mpp_buffer_sync_end(streambuf);
870*437bfbebSnyanmisaka         mpp_buffer_sync_end(JpegHalCtx->pTableBase);
871*437bfbebSnyanmisaka         if (ret != MPP_OK) {
872*437bfbebSnyanmisaka             mpp_err_f("generate registers failed\n");
873*437bfbebSnyanmisaka             goto RET;
874*437bfbebSnyanmisaka         }
875*437bfbebSnyanmisaka     }
876*437bfbebSnyanmisaka 
877*437bfbebSnyanmisaka     return ret;
878*437bfbebSnyanmisaka RET:
879*437bfbebSnyanmisaka     syn->dec.valid = 0;
880*437bfbebSnyanmisaka     syn->dec.flags.parse_err = 1;
881*437bfbebSnyanmisaka 
882*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
883*437bfbebSnyanmisaka     return ret;
884*437bfbebSnyanmisaka }
885*437bfbebSnyanmisaka 
hal_jpegd_vdpu2_start(void * hal,HalTaskInfo * task)886*437bfbebSnyanmisaka MPP_RET hal_jpegd_vdpu2_start(void *hal, HalTaskInfo *task)
887*437bfbebSnyanmisaka {
888*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
889*437bfbebSnyanmisaka     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
890*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)JpegHalCtx->regs;
891*437bfbebSnyanmisaka 
892*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
893*437bfbebSnyanmisaka     if (task->dec.flags.parse_err)
894*437bfbebSnyanmisaka         goto __RETURN;
895*437bfbebSnyanmisaka 
896*437bfbebSnyanmisaka     do {
897*437bfbebSnyanmisaka         MppDevRegWrCfg wr_cfg;
898*437bfbebSnyanmisaka         MppDevRegRdCfg rd_cfg;
899*437bfbebSnyanmisaka         RK_U32 reg_size = mpp_get_ioctl_version() ?
900*437bfbebSnyanmisaka                           sizeof(((JpegdIocRegInfo *)0)->regs) :
901*437bfbebSnyanmisaka                           sizeof(JpegdIocRegInfo) - EXTRA_INFO_SIZE;
902*437bfbebSnyanmisaka 
903*437bfbebSnyanmisaka         wr_cfg.reg = regs;
904*437bfbebSnyanmisaka         wr_cfg.size = reg_size;
905*437bfbebSnyanmisaka         wr_cfg.offset = 0;
906*437bfbebSnyanmisaka 
907*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_REG_WR, &wr_cfg);
908*437bfbebSnyanmisaka         if (ret) {
909*437bfbebSnyanmisaka             mpp_err_f("set register write failed %d\n", ret);
910*437bfbebSnyanmisaka             goto __RETURN;
911*437bfbebSnyanmisaka         }
912*437bfbebSnyanmisaka 
913*437bfbebSnyanmisaka         reg_size = sizeof(((JpegdIocRegInfo *)0)->regs);
914*437bfbebSnyanmisaka 
915*437bfbebSnyanmisaka         rd_cfg.reg = regs;
916*437bfbebSnyanmisaka         rd_cfg.size = reg_size;
917*437bfbebSnyanmisaka         rd_cfg.offset = 0;
918*437bfbebSnyanmisaka 
919*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_REG_RD, &rd_cfg);
920*437bfbebSnyanmisaka         if (ret) {
921*437bfbebSnyanmisaka             mpp_err_f("set register read failed %d\n", ret);
922*437bfbebSnyanmisaka             goto __RETURN;
923*437bfbebSnyanmisaka         }
924*437bfbebSnyanmisaka 
925*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_CMD_SEND, NULL);
926*437bfbebSnyanmisaka         if (ret) {
927*437bfbebSnyanmisaka             mpp_err_f("send cmd failed %d\n", ret);
928*437bfbebSnyanmisaka             goto __RETURN;
929*437bfbebSnyanmisaka         }
930*437bfbebSnyanmisaka     } while (0);
931*437bfbebSnyanmisaka 
932*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
933*437bfbebSnyanmisaka     return ret;
934*437bfbebSnyanmisaka 
935*437bfbebSnyanmisaka __RETURN:
936*437bfbebSnyanmisaka     task->dec.flags.parse_err = 1;
937*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
938*437bfbebSnyanmisaka     return ret;
939*437bfbebSnyanmisaka }
940*437bfbebSnyanmisaka 
hal_jpegd_vdpu2_wait(void * hal,HalTaskInfo * task)941*437bfbebSnyanmisaka MPP_RET hal_jpegd_vdpu2_wait(void *hal, HalTaskInfo *task)
942*437bfbebSnyanmisaka {
943*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
944*437bfbebSnyanmisaka     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
945*437bfbebSnyanmisaka     JpegRegSet *reg_out = JpegHalCtx->regs;
946*437bfbebSnyanmisaka     RK_U32 errinfo = 1;
947*437bfbebSnyanmisaka 
948*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
949*437bfbebSnyanmisaka     if (task->dec.flags.parse_err)
950*437bfbebSnyanmisaka         goto __SKIP_HARD;
951*437bfbebSnyanmisaka 
952*437bfbebSnyanmisaka     ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_CMD_POLL, NULL);
953*437bfbebSnyanmisaka     if (ret) {
954*437bfbebSnyanmisaka         task->dec.flags.parse_err = 1;
955*437bfbebSnyanmisaka         mpp_err_f("poll cmd failed %d\n", ret);
956*437bfbebSnyanmisaka     }
957*437bfbebSnyanmisaka 
958*437bfbebSnyanmisaka __SKIP_HARD:
959*437bfbebSnyanmisaka     if (JpegHalCtx->dec_cb) {
960*437bfbebSnyanmisaka         DecCbHalDone param;
961*437bfbebSnyanmisaka 
962*437bfbebSnyanmisaka         param.task = (void *)&task->dec;
963*437bfbebSnyanmisaka         param.regs = (RK_U32 *)reg_out;
964*437bfbebSnyanmisaka         if (reg_out->reg55_Interrupt.sw_dec_bus_int) {
965*437bfbebSnyanmisaka             mpp_err_f("IRQ BUS ERROR!");
966*437bfbebSnyanmisaka         } else if (reg_out->reg55_Interrupt.sw_dec_error_int) {
967*437bfbebSnyanmisaka             mpp_err_f("IRQ STREAM ERROR!");
968*437bfbebSnyanmisaka         } else if (reg_out->reg55_Interrupt.sw_dec_timeout) {
969*437bfbebSnyanmisaka             mpp_err_f("IRQ TIMEOUT!");
970*437bfbebSnyanmisaka         } else if (reg_out->reg55_Interrupt.sw_dec_buffer_int) {
971*437bfbebSnyanmisaka             mpp_err_f("IRQ BUFFER EMPTY!");
972*437bfbebSnyanmisaka         } else if (reg_out->reg55_Interrupt.sw_dec_irq) {
973*437bfbebSnyanmisaka             errinfo = 0;
974*437bfbebSnyanmisaka             jpegd_dbg_result("DECODE SUCCESS!");
975*437bfbebSnyanmisaka         }
976*437bfbebSnyanmisaka         param.hard_err = errinfo;
977*437bfbebSnyanmisaka         mpp_callback(JpegHalCtx->dec_cb, &param);
978*437bfbebSnyanmisaka     }
979*437bfbebSnyanmisaka 
980*437bfbebSnyanmisaka     /* debug information */
981*437bfbebSnyanmisaka     if (jpegd_debug & JPEGD_DBG_IO) {
982*437bfbebSnyanmisaka         static FILE *jpg_file;
983*437bfbebSnyanmisaka         static char name[64];
984*437bfbebSnyanmisaka         MppBuffer outputBuf = NULL;
985*437bfbebSnyanmisaka         void *base = NULL;
986*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, task->dec.output,
987*437bfbebSnyanmisaka                               SLOT_BUFFER, &outputBuf);
988*437bfbebSnyanmisaka         base = mpp_buffer_get_ptr(outputBuf);
989*437bfbebSnyanmisaka 
990*437bfbebSnyanmisaka         snprintf(name, sizeof(name) - 1, "/data/tmp/output%02d.yuv",
991*437bfbebSnyanmisaka                  JpegHalCtx->output_yuv_count);
992*437bfbebSnyanmisaka         jpg_file = fopen(name, "wb+");
993*437bfbebSnyanmisaka         if (jpg_file) {
994*437bfbebSnyanmisaka             JpegdSyntax *syntax = (JpegdSyntax *)task->dec.syntax.data;
995*437bfbebSnyanmisaka             RK_U32 width = syntax->hor_stride;
996*437bfbebSnyanmisaka             RK_U32 height = syntax->ver_stride;
997*437bfbebSnyanmisaka 
998*437bfbebSnyanmisaka             fwrite(base, width * height * 3 / 2, 1, jpg_file);
999*437bfbebSnyanmisaka             jpegd_dbg_io("frame_%02d output YUV(%d*%d) saving to %s\n",
1000*437bfbebSnyanmisaka                          JpegHalCtx->output_yuv_count,
1001*437bfbebSnyanmisaka                          width, height, name);
1002*437bfbebSnyanmisaka             fclose(jpg_file);
1003*437bfbebSnyanmisaka             JpegHalCtx->output_yuv_count++;
1004*437bfbebSnyanmisaka         }
1005*437bfbebSnyanmisaka     }
1006*437bfbebSnyanmisaka 
1007*437bfbebSnyanmisaka     memset(&reg_out->reg55_Interrupt, 0, sizeof(RK_U32));
1008*437bfbebSnyanmisaka 
1009*437bfbebSnyanmisaka     jpegd_dbg_func("exit\n");
1010*437bfbebSnyanmisaka     return ret;
1011*437bfbebSnyanmisaka }
1012*437bfbebSnyanmisaka 
hal_jpegd_vdpu2_control(void * hal,MpiCmd cmd_type,void * param)1013*437bfbebSnyanmisaka MPP_RET hal_jpegd_vdpu2_control(void *hal, MpiCmd cmd_type,
1014*437bfbebSnyanmisaka                                 void *param)
1015*437bfbebSnyanmisaka {
1016*437bfbebSnyanmisaka     jpegd_dbg_func("enter\n");
1017*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
1018*437bfbebSnyanmisaka     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
1019*437bfbebSnyanmisaka     if (NULL == JpegHalCtx) {
1020*437bfbebSnyanmisaka         mpp_err_f("NULL pointer");
1021*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
1022*437bfbebSnyanmisaka     }
1023*437bfbebSnyanmisaka 
1024*437bfbebSnyanmisaka     switch (cmd_type) {
1025*437bfbebSnyanmisaka     case MPP_DEC_SET_OUTPUT_FORMAT: {
1026*437bfbebSnyanmisaka         JpegHalCtx->output_fmt = *((MppFrameFormat *)param);
1027*437bfbebSnyanmisaka         JpegHalCtx->set_output_fmt_flag = 1;
1028*437bfbebSnyanmisaka         jpegd_dbg_hal("output_format: 0x%x\n", JpegHalCtx->output_fmt);
1029*437bfbebSnyanmisaka 
1030*437bfbebSnyanmisaka         if (!MPP_FRAME_FMT_IS_YUV(JpegHalCtx->output_fmt) && !MPP_FRAME_FMT_IS_RGB(JpegHalCtx->output_fmt)) {
1031*437bfbebSnyanmisaka             mpp_err_f("invalid output format 0x%x\n", JpegHalCtx->output_fmt);
1032*437bfbebSnyanmisaka             ret = MPP_ERR_VALUE;
1033*437bfbebSnyanmisaka         }
1034*437bfbebSnyanmisaka     } break;
1035*437bfbebSnyanmisaka     default :
1036*437bfbebSnyanmisaka         break;
1037*437bfbebSnyanmisaka     }
1038*437bfbebSnyanmisaka 
1039*437bfbebSnyanmisaka     jpegd_dbg_func("exit ret %d\n", ret);
1040*437bfbebSnyanmisaka     return  ret;
1041*437bfbebSnyanmisaka }
1042