1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "hal_avsd_vdpu2"
18
19 #include <string.h>
20
21 #include "mpp_debug.h"
22 #include "mpp_common.h"
23 #include "mpp_mem.h"
24 #include "mpp_device.h"
25 #include "mpp_dec_cb_param.h"
26
27 #include "hal_avsd_base.h"
28 #include "hal_avsd_vdpu2.h"
29 #include "hal_avsd_vdpu2_reg.h"
30
set_defalut_parameters(AvsdHalCtx_t * p_hal)31 static MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal)
32 {
33 AvsdVdpu2Regs_t *p_regs = (AvsdVdpu2Regs_t *)p_hal->p_regs;
34
35 p_regs->sw54.dec_out_endian = 1;
36 p_regs->sw54.dec_in_endian = 0;
37 p_regs->sw54.dec_strendian_e = 1;
38 p_regs->sw56.dec_max_burlen = 16;
39 p_regs->sw50.dec_ascmd0_dis = 0;
40
41 p_regs->sw50.adv_pref_dis = 0;
42 p_regs->sw52.adv_pref_thrd = 8;
43 p_regs->sw50.adtion_latency = 0;
44
45 p_regs->sw56.dec_data_discd_en = 0;
46 p_regs->sw54.dec_out_wordsp = 1;
47 p_regs->sw54.dec_in_wordsp = 1;
48 p_regs->sw54.dec_strm_wordsp = 1;
49 p_regs->sw55.timeout_det_sts = 0;
50 p_regs->sw57.dec_clkgate_en = 1;
51 p_regs->sw55.dec_irq_dis = 0;
52
53 p_regs->sw56.dec_axi_id_rd = 0xFF;
54 p_regs->sw56.dec_axi_id_wr = 0;
55
56 p_regs->sw59.pred_bc_tap_0_0 = 0x3FF;
57 p_regs->sw59.pred_bc_tap_0_1 = 5;
58 p_regs->sw59.pred_bc_tap_0_2 = 5;
59 p_regs->sw153.pred_bc_tap_0_3 = 0x3FF;
60 p_regs->sw153.pred_bc_tap_1_0 = 1;
61 p_regs->sw153.pred_bc_tap_1_1 = 7;
62 p_regs->sw154.pred_bc_tap_1_2 = 7;
63 p_regs->sw154.pred_bc_tap_1_3 = 1;
64
65 p_regs->sw50.dec_tiled_lsb = 0;
66
67 return MPP_OK;
68 }
69
set_regs_parameters(AvsdHalCtx_t * p_hal,HalDecTask * task)70 static MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task)
71 {
72 MPP_RET ret = MPP_ERR_UNKNOW;
73
74 AvsdSyntax_t *p_syn = &p_hal->syn;
75 AvsdVdpu2Regs_t *p_regs = (AvsdVdpu2Regs_t *)p_hal->p_regs;
76
77 set_defalut_parameters(p_hal);
78
79 p_regs->sw57.timeout_sts_en = 1;
80 p_regs->sw57.dec_clkgate_en = 1;
81 p_regs->sw55.dec_irq_dis = 0;
82
83 //!< set wrok_out pic info
84 if (p_hal->work_out < 0) {
85 p_hal->work_out = get_queue_pic(p_hal);
86 if (p_hal->work_out < 0) {
87 ret = MPP_NOK;
88 mpp_err_f("cannot get a pic_info buffer.\n");
89 goto __FAILED;
90 }
91 }
92 {
93 AvsdHalPic_t *p_work_out = &p_hal->pic[p_hal->work_out];
94
95 p_work_out->slot_idx = task->output;
96 p_work_out->pic_code_type = p_syn->pp.picCodingType;
97 p_work_out->picture_distance = p_syn->pp.pictureDistance;
98 }
99 //!< set register
100 p_regs->sw120.pic_mb_width = (p_syn->pp.horizontalSize + 15) >> 4;
101 p_regs->sw53.dec_fmt_sel = 11; //!< DEC_MODE_AVS
102
103 if (p_syn->pp.pictureStructure == FRAMEPICTURE) {
104 p_regs->sw57.pic_interlace_e = 0; //!< interlace_e
105 p_regs->sw57.pic_fieldmode_e = 0; //!< fieldmode_e
106 p_regs->sw57.pic_topfield_e = 0; //!< topfield_e
107 } else {
108 p_regs->sw57.pic_interlace_e = 1;
109 p_regs->sw57.pic_fieldmode_e = 1;
110 p_regs->sw57.pic_topfield_e = p_hal->first_field;
111 }
112
113 p_regs->sw120.pic_mb_height_p = (p_syn->pp.verticalSize + 15) >> 4;
114 p_regs->sw121.avs_h_ext = (p_syn->pp.verticalSize + 15) >> 12;
115 p_regs->sw57.pic_b_e = (p_syn->pp.picCodingType == BFRAME);
116 p_regs->sw57.pic_inter_e = (p_syn->pp.picCodingType != IFRAME) ? 1 : 0;
117
118 p_regs->sw122.strm_start_bit = 8 * (p_hal->data_offset & 0x7);
119 p_hal->data_offset = (p_hal->data_offset & ~0x7);
120 p_regs->sw64.rlc_vlc_st_adr = get_packet_fd(p_hal, task->input);
121 mpp_dev_set_reg_offset(p_hal->dev, 64, p_hal->data_offset);
122 p_regs->sw51.stream_len = p_syn->bitstream_size - p_hal->data_offset;
123 p_regs->sw50.dec_fixed_quant = p_syn->pp.fixedPictureQp;
124 p_regs->sw51.init_qp = p_syn->pp.pictureQp;
125
126 p_regs->sw63.dec_out_st_adr = get_frame_fd(p_hal, task->output);
127 if (p_syn->pp.pictureStructure == FIELDPICTURE && !p_hal->first_field) {
128 //!< start of bottom field line
129 mpp_dev_set_reg_offset(p_hal->dev, 63, p_syn->pp.horizontalSize);
130 }
131 {
132 RK_S32 tmp_fwd = -1;
133 RK_S32 refer0 = -1;
134 RK_S32 refer1 = -1;
135
136 tmp_fwd = (p_hal->work1 < 0) ? p_hal->work0 : p_hal->work1;
137 tmp_fwd = (tmp_fwd < 0) ? p_hal->work_out : tmp_fwd;
138
139 refer0 = (task->refer[0] < 0) ? task->output : task->refer[0];
140 refer1 = (task->refer[1] < 0) ? refer0 : task->refer[1];
141 if (!p_hal->first_field
142 && p_syn->pp.pictureStructure == FIELDPICTURE
143 && p_syn->pp.picCodingType != BFRAME) {
144 p_regs->sw131.refer0_base = get_frame_fd(p_hal, task->output);
145 p_regs->sw148.refer1_base = get_frame_fd(p_hal, refer0);
146 p_regs->sw134.refer2_base = get_frame_fd(p_hal, refer0);
147 p_regs->sw135.refer3_base = get_frame_fd(p_hal, refer1);
148 } else {
149 p_regs->sw131.refer0_base = get_frame_fd(p_hal, refer0);
150 p_regs->sw148.refer1_base = get_frame_fd(p_hal, refer0);
151 p_regs->sw134.refer2_base = get_frame_fd(p_hal, refer1);
152 p_regs->sw135.refer3_base = get_frame_fd(p_hal, refer1);
153 }
154 }
155 //!< block distances
156 if (p_syn->pp.pictureStructure == FRAMEPICTURE) {
157 if (p_syn->pp.picCodingType == BFRAME) {
158 RK_S32 tmp = 0;
159 //!< current to future anchor
160 if (p_hal->work0 >= 0) {
161 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
162 2 * p_syn->pp.pictureDistance + 512) & 0x1FF;
163 }
164 //!< prevent division by zero
165 if (!tmp) tmp = 2;
166 p_regs->sw133.ref_dist_cur_2 = tmp;
167 p_regs->sw133.ref_dist_cur_3 = tmp;
168 p_regs->sw147.ref_invd_cur_2 = 512 / tmp;
169 p_regs->sw147.ref_invd_cur_3 = 512 / tmp;
170
171 //!< current to past anchor
172 if (p_hal->work1 >= 0) {
173 tmp = (2 * p_syn->pp.pictureDistance -
174 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
175 if (!tmp) tmp = 2;
176 }
177 p_regs->sw132.ref_dist_cur_0 = tmp;
178 p_regs->sw132.ref_dist_cur_1 = tmp;
179 p_regs->sw146.ref_invd_cur_0 = 512 / tmp;
180 p_regs->sw146.ref_invd_cur_1 = 512 / tmp;
181 //!< future anchor to past anchor
182 if (p_hal->work0 >= 0 && p_hal->work1 >= 0) {
183 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
184 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
185 if (!tmp) tmp = 2;
186 }
187 tmp = 16384 / tmp;
188 p_regs->sw129.ref_invd_col_0 = tmp;
189 p_regs->sw129.ref_invd_col_1 = tmp;
190 //!< future anchor to previous past anchor
191 tmp = p_hal->future2prev_past_dist;
192 tmp = 16384 / tmp;
193 p_regs->sw130.ref_invd_col_2 = tmp;
194 p_regs->sw130.ref_invd_col_3 = tmp;
195 } else {
196 RK_S32 tmp = 0;
197 //!< current to past anchor
198 if (p_hal->work0 >= 0) {
199 tmp = (2 * p_syn->pp.pictureDistance -
200 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF;
201 }
202 if (!tmp) tmp = 2;
203 p_regs->sw132.ref_dist_cur_0 = tmp;
204 p_regs->sw132.ref_dist_cur_1 = tmp;
205 p_regs->sw146.ref_invd_cur_0 = 512 / tmp;
206 p_regs->sw146.ref_invd_cur_1 = 512 / tmp;
207 //!< current to previous past anchor
208 if (p_hal->work1 >= 0) {
209 tmp = (2 * p_syn->pp.pictureDistance -
210 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
211 if (!tmp) tmp = 2;
212 }
213 //!< this will become "future to previous past" for next B
214 p_hal->future2prev_past_dist = tmp;
215
216 p_regs->sw133.ref_dist_cur_2 = tmp;
217 p_regs->sw133.ref_dist_cur_3 = tmp;
218 p_regs->sw147.ref_invd_cur_2 = 512 / tmp;
219 p_regs->sw147.ref_invd_cur_3 = 512 / tmp;
220
221 p_regs->sw129.ref_invd_col_0 = 0;
222 p_regs->sw129.ref_invd_col_1 = 0;
223 p_regs->sw130.ref_invd_col_2 = 0;
224 p_regs->sw130.ref_invd_col_3 = 0;
225 }
226 } else {
227 //!< field interlaced
228 if (p_syn->pp.picCodingType == BFRAME) {
229 RK_S32 tmp = 0;
230 //!< block distances
231 if (p_hal->work0 >= 0) {
232 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
233 2 * p_syn->pp.pictureDistance + 512) & 0x1FF;
234 }
235 //!< prevent division by zero
236 if (!tmp) tmp = 2;
237
238 if (p_hal->first_field) {
239 p_regs->sw133.ref_dist_cur_2 = tmp;
240 p_regs->sw133.ref_dist_cur_3 = tmp + 1;
241 p_regs->sw147.ref_invd_cur_2 = 512 / tmp;
242 p_regs->sw147.ref_invd_cur_3 = 512 / (tmp + 1);
243 } else {
244 p_regs->sw133.ref_dist_cur_2 = tmp - 1;
245 p_regs->sw133.ref_dist_cur_3 = tmp;
246 p_regs->sw147.ref_invd_cur_2 = 512 / (tmp - 1);
247 p_regs->sw147.ref_invd_cur_3 = 512 / tmp;
248 }
249
250 if (p_hal->work1 >= 0) {
251 tmp = (2 * p_syn->pp.pictureDistance -
252 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
253 if (!tmp) tmp = 2;
254 }
255 if (p_hal->first_field) {
256 p_regs->sw132.ref_dist_cur_0 = (tmp - 1);
257 p_regs->sw132.ref_dist_cur_1 = tmp;
258 p_regs->sw146.ref_invd_cur_0 = 512 / (tmp - 1);
259 p_regs->sw146.ref_invd_cur_1 = 512 / tmp;
260 } else {
261 p_regs->sw132.ref_dist_cur_0 = tmp;
262 p_regs->sw132.ref_dist_cur_1 = tmp + 1;
263 p_regs->sw146.ref_invd_cur_0 = 512 / tmp;
264 p_regs->sw146.ref_invd_cur_1 = 512 / (tmp + 1);
265 }
266
267 if (p_hal->work0 >= 0 && p_hal->work1 >= 0) {
268 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
269 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
270 if (!tmp) tmp = 2;
271 }
272
273 if (p_syn->pp.pbFieldEnhancedFlag && !p_hal->first_field) {
274 //!< in this case, BlockDistanceRef is different with before, the mvRef points to top field
275 p_regs->sw129.ref_invd_col_0 = 16384 / (tmp - 1);
276 p_regs->sw129.ref_invd_col_1 = 16384 / tmp;
277
278 //!< future anchor to previous past anchor
279 tmp = p_hal->future2prev_past_dist;
280
281 p_regs->sw130.ref_invd_col_2 = 16384 / (tmp - 1);
282 p_regs->sw130.ref_invd_col_3 = 16384 / tmp;
283 } else {
284 if (p_hal->first_field) {
285 p_regs->sw129.ref_invd_col_0 = 16384 / (tmp - 1);
286 p_regs->sw129.ref_invd_col_1 = 16384 / tmp;
287 } else {
288 p_regs->sw129.ref_invd_col_0 = 16384;
289 p_regs->sw129.ref_invd_col_1 = 16384 / tmp;
290 p_regs->sw130.ref_invd_col_2 = 16384 / (tmp + 1);
291 }
292
293 //!< future anchor to previous past anchor
294 tmp = p_hal->future2prev_past_dist;
295
296 if (p_hal->first_field) {
297 p_regs->sw130.ref_invd_col_2 = 16384 / (tmp - 1);
298 p_regs->sw130.ref_invd_col_3 = 16384 / tmp;
299 } else {
300 p_regs->sw130.ref_invd_col_3 = 16384 / tmp;
301 }
302 }
303 } else {
304 RK_S32 tmp = 0;
305 if (p_hal->work0 >= 0) {
306 tmp = (2 * p_syn->pp.pictureDistance -
307 2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF;
308 }
309 if (!tmp) tmp = 2;
310
311 if (!p_hal->first_field) {
312 p_regs->sw132.ref_dist_cur_0 = 1;
313 p_regs->sw133.ref_dist_cur_2 = tmp + 1;
314
315 p_regs->sw146.ref_invd_cur_0 = 512;
316 p_regs->sw147.ref_invd_cur_2 = 512 / (tmp + 1);
317 } else {
318 p_regs->sw132.ref_dist_cur_0 = tmp - 1;
319 p_regs->sw146.ref_invd_cur_0 = 512 / (tmp - 1);
320 }
321 p_regs->sw132.ref_dist_cur_1 = tmp;
322 p_regs->sw146.ref_invd_cur_1 = 512 / tmp;
323
324 if (p_hal->work1 >= 0) {
325 tmp = (2 * p_syn->pp.pictureDistance -
326 2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
327 if (!tmp) tmp = 2;
328 }
329 //!< this will become "future to previous past" for next B
330 p_hal->future2prev_past_dist = tmp;
331 if (p_hal->first_field) {
332 p_regs->sw133.ref_dist_cur_2 = tmp - 1;
333 p_regs->sw133.ref_dist_cur_3 = tmp;
334
335 p_regs->sw147.ref_invd_cur_2 = 512 / (tmp - 1);
336 p_regs->sw147.ref_invd_cur_3 = 512 / tmp;
337 } else {
338 p_regs->sw133.ref_dist_cur_3 = tmp;
339 p_regs->sw147.ref_invd_cur_3 = 512 / tmp;
340 }
341
342 p_regs->sw129.ref_invd_col_0 = 0;
343 p_regs->sw129.ref_invd_col_1 = 0;
344 p_regs->sw130.ref_invd_col_2 = 0;
345 p_regs->sw130.ref_invd_col_3 = 0;
346 }
347 }
348
349 p_regs->sw52.startmb_x = 0;
350 p_regs->sw52.startmb_y = 0;
351
352 p_regs->sw50.filtering_dis = p_syn->pp.loopFilterDisable;
353 p_regs->sw122.alpha_offset = p_syn->pp.alphaOffset;
354 p_regs->sw122.beta_offset = p_syn->pp.betaOffset;
355 p_regs->sw50.skip_mode = p_syn->pp.skipModeFlag;
356 p_regs->sw120.pic_refer_flag = p_syn->pp.pictureReferenceFlag;
357
358 if (p_syn->pp.picCodingType == PFRAME
359 || (p_syn->pp.picCodingType == IFRAME && !p_hal->first_field)) {
360 p_regs->sw57.dmmv_wr_en = 1;
361 } else {
362 p_regs->sw57.dmmv_wr_en = 0;
363 }
364
365 //!< set mv base
366 p_regs->sw62.dmmv_st_adr = mpp_buffer_get_fd(p_hal->mv_buf);
367 if (p_hal->first_field ||
368 (p_syn->pp.picCodingType == BFRAME && p_hal->prev_pic_structure)) {
369 } else {
370 RK_U32 frame_width = 0, frame_height = 0, offset = 0;
371 frame_width = (p_syn->pp.horizontalSize + 15) >> 4;
372 if (p_syn->pp.progressiveFrame)
373 frame_height = (p_syn->pp.verticalSize + 15) >> 4;
374 else
375 frame_height = 2 * ((p_syn->pp.verticalSize + 31) >> 5);
376 offset = MPP_ALIGN(frame_width * frame_height / 2, 2) * 16;
377 mpp_dev_set_reg_offset(p_hal->dev, 62, offset);
378 }
379 {
380 RK_U32 pic_type = 0;
381 RK_U32 prev_anc_type = 0;
382 if (p_hal->work0 >= 0) {
383 pic_type = p_hal->pic[p_hal->work0].pic_type;
384 }
385 prev_anc_type = !pic_type || (!p_hal->first_field && !p_hal->prev_pic_structure);
386 p_regs->sw136.prev_anc_type = prev_anc_type;
387 }
388 //!< b-picture needs to know if future reference is field or frame coded
389 // p_regs->sw134.refer2_field_e = (!p_hal->prev_pic_structure) ? 1 : 0;
390 // p_regs->sw135.refer3_field_e = (!p_hal->prev_pic_structure) ? 1 : 0;
391 if (!p_hal->prev_pic_structure) {
392 mpp_dev_set_reg_offset(p_hal->dev, 134, 2);
393 mpp_dev_set_reg_offset(p_hal->dev, 135, 3);
394 }
395
396 p_regs->sw57.dec_out_dis = 0;
397 p_regs->sw57.dec_e = 1;
398
399 return MPP_OK;
400 __FAILED:
401 return ret;
402 }
403
update_parameters(AvsdHalCtx_t * p_hal)404 static MPP_RET update_parameters(AvsdHalCtx_t *p_hal)
405 {
406 AvsdSyntax_t *p_syn = &p_hal->syn;
407
408 if (p_syn->pp.pictureStructure == FRAMEPICTURE || !p_hal->first_field) {
409 p_hal->first_field = 1;
410 if (p_syn->pp.picCodingType != BFRAME) {
411 RK_S32 temp = p_hal->work1;
412
413 p_hal->work1 = p_hal->work0;
414 p_hal->work0 = p_hal->work_out;
415
416 if (p_hal->work_out >= 0)
417 p_hal->pic[p_hal->work_out].pic_type = p_syn->pp.picCodingType == IFRAME;
418 p_hal->work_out = temp;
419 p_hal->prev_pic_structure = p_syn->pp.pictureStructure;
420 }
421 p_hal->prev_pic_code_type = p_syn->pp.picCodingType;
422 } else {
423 p_hal->first_field = 0;
424 }
425
426 return MPP_OK;
427 }
428
repeat_other_field(AvsdHalCtx_t * p_hal,HalTaskInfo * task)429 static MPP_RET repeat_other_field(AvsdHalCtx_t *p_hal, HalTaskInfo *task)
430 {
431 RK_U8 i = 0;
432 RK_U8 *pdata = NULL;
433 MppBuffer mbuffer = NULL;
434 MPP_RET ret = MPP_ERR_UNKNOW;
435 AvsdVdpu2Regs_t *p_regs = (AvsdVdpu2Regs_t *)p_hal->p_regs;
436
437 //!< re-find start code and calculate offset
438 p_hal->data_offset = p_regs->sw64.rlc_vlc_st_adr >> 10;
439 p_hal->data_offset += p_hal->syn.bitstream_offset;
440 p_hal->data_offset -= MPP_MIN(p_hal->data_offset, 8);
441
442 mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &mbuffer);
443 pdata = (RK_U8 *)mpp_buffer_get_ptr(mbuffer) + p_hal->data_offset;
444
445 while (i < 16) {
446 if (pdata[i] == 0 && pdata[i + 1] == 0 && pdata[i + 2] == 1) {
447 p_hal->data_offset += i;
448 break;
449 }
450 i++;
451 }
452
453 AVSD_HAL_DBG(AVSD_HAL_DBG_OFFSET, "frame_no %d idx %d offset %x\n",
454 p_hal->frame_no, i, p_hal->data_offset);
455
456 //!< re-generate register
457 FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec));
458 hal_avsd_vdpu2_start((void *)p_hal, task);
459 hal_avsd_vdpu2_wait((void *)p_hal, task);
460
461 return ret = MPP_OK;
462 __FAILED:
463 return ret;
464 }
465
466
467 /*!
468 ***********************************************************************
469 * \brief
470 * init
471 ***********************************************************************
472 */
473 //extern "C"
hal_avsd_vdpu2_init(void * decoder,MppHalCfg * cfg)474 MPP_RET hal_avsd_vdpu2_init(void *decoder, MppHalCfg *cfg)
475 {
476 MPP_RET ret = MPP_ERR_UNKNOW;
477 RK_U32 buf_size = 0;
478 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
479
480 AVSD_HAL_TRACE("AVS_vdpu2 In.");
481
482 buf_size = (1920 * 1088) * 2;
483 FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->mv_buf, buf_size));
484
485 p_hal->p_regs = mpp_calloc_size(RK_U32, sizeof(AvsdVdpu2Regs_t));
486 MEM_CHECK(ret, p_hal->p_regs);
487
488 mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align);
489 mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align);
490 mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align);
491
492 p_hal->regs_num = 159;
493 //!< initial for control
494 p_hal->first_field = 1;
495 p_hal->prev_pic_structure = 0; //!< field
496
497 memset(p_hal->pic, 0, sizeof(p_hal->pic));
498 p_hal->work_out = -1;
499 p_hal->work0 = -1;
500 p_hal->work1 = -1;
501
502 AVSD_HAL_TRACE("Out.");
503 (void)cfg;
504 return ret = MPP_OK;
505 __FAILED:
506 return ret;
507
508 }
509 /*!
510 ***********************************************************************
511 * \brief
512 * deinit
513 ***********************************************************************
514 */
515 //extern "C"
hal_avsd_vdpu2_deinit(void * decoder)516 MPP_RET hal_avsd_vdpu2_deinit(void *decoder)
517 {
518 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
519
520 AVSD_HAL_TRACE("In.");
521
522 if (p_hal->mv_buf) {
523 mpp_buffer_put(p_hal->mv_buf);
524 p_hal->mv_buf = NULL;
525 }
526 MPP_FREE(p_hal->p_regs);
527
528 AVSD_HAL_TRACE("Out.");
529
530 return MPP_OK;
531 }
532 /*!
533 ***********************************************************************
534 * \brief
535 * generate register
536 ***********************************************************************
537 */
538 //extern "C"
hal_avsd_vdpu2_gen_regs(void * decoder,HalTaskInfo * task)539 MPP_RET hal_avsd_vdpu2_gen_regs(void *decoder, HalTaskInfo *task)
540 {
541 MPP_RET ret = MPP_ERR_UNKNOW;
542 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
543
544 AVSD_HAL_TRACE("In.");
545 if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
546 !p_hal->dec_cfg->base.disable_error) {
547 goto __RETURN;
548 }
549 p_hal->data_offset = p_hal->syn.bitstream_offset;
550
551 FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec));
552 __RETURN:
553 AVSD_HAL_TRACE("Out.");
554
555 return ret = MPP_OK;
556 __FAILED:
557 return ret;
558
559 }
560 /*!
561 ***********************************************************************
562 * \brief h
563 * start hard
564 ***********************************************************************
565 */
566 //extern "C"
hal_avsd_vdpu2_start(void * decoder,HalTaskInfo * task)567 MPP_RET hal_avsd_vdpu2_start(void *decoder, HalTaskInfo *task)
568 {
569 MPP_RET ret = MPP_ERR_UNKNOW;
570 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
571
572 AVSD_HAL_TRACE("In.");
573
574 if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
575 !p_hal->dec_cfg->base.disable_error) {
576 goto __RETURN;
577 }
578
579 do {
580 MppDevRegWrCfg wr_cfg;
581 MppDevRegRdCfg rd_cfg;
582 RK_U32 reg_size = 159 * sizeof(RK_U32);
583
584 wr_cfg.reg = p_hal->p_regs;
585 wr_cfg.size = reg_size;
586 wr_cfg.offset = 0;
587
588 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg);
589 if (ret) {
590 mpp_err_f("set register write failed %d\n", ret);
591 break;
592 }
593
594 rd_cfg.reg = p_hal->p_regs;
595 rd_cfg.size = reg_size;
596 rd_cfg.offset = 0;
597
598 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg);
599 if (ret) {
600 mpp_err_f("set register read failed %d\n", ret);
601 break;
602 }
603
604 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL);
605 if (ret) {
606 mpp_err_f("send cmd failed %d\n", ret);
607 break;
608 }
609 } while (0);
610
611 __RETURN:
612 AVSD_HAL_TRACE("Out.");
613 return ret = MPP_OK;
614 }
615 /*!
616 ***********************************************************************
617 * \brief
618 * wait hard
619 ***********************************************************************
620 */
621 //extern "C"
hal_avsd_vdpu2_wait(void * decoder,HalTaskInfo * task)622 MPP_RET hal_avsd_vdpu2_wait(void *decoder, HalTaskInfo *task)
623 {
624 MPP_RET ret = MPP_ERR_UNKNOW;
625 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
626
627 AVSD_HAL_TRACE("In.");
628
629 if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
630 !p_hal->dec_cfg->base.disable_error) {
631 goto __SKIP_HARD;
632 }
633
634 ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL);
635 if (ret)
636 mpp_err_f("poll cmd failed %d\n", ret);
637
638 __SKIP_HARD:
639 if (p_hal->dec_cb) {
640 DecCbHalDone param;
641
642 param.task = (void *)&task->dec;
643 param.regs = (RK_U32 *)p_hal->p_regs;
644
645 if (!((AvsdVdpu2Regs_t *)p_hal->p_regs)->sw55.dec_rdy_sts) {
646 param.hard_err = 1;
647 } else
648 param.hard_err = 0;
649
650 mpp_callback(p_hal->dec_cb, ¶m);
651 AVSD_HAL_DBG(AVSD_HAL_DBG_WAIT, "reg[55]=%08x, ref=%d, dpberr=%d, harderr=%d\n",
652 p_hal->p_regs[55], task->dec.flags.used_for_ref, task->dec.flags.ref_err, param.hard_err);
653 }
654
655 update_parameters(p_hal);
656 memset(&p_hal->p_regs[55], 0, sizeof(RK_U32));
657 if (!p_hal->first_field && p_hal->syn.pp.pictureStructure == FIELDPICTURE &&
658 ((!task->dec.flags.parse_err && !task->dec.flags.ref_err) ||
659 p_hal->dec_cfg->base.disable_error)) {
660 repeat_other_field(p_hal, task);
661 }
662 p_hal->frame_no++;
663
664 AVSD_HAL_TRACE("Out.");
665 return ret = MPP_OK;
666 }
667 /*!
668 ***********************************************************************
669 * \brief
670 * reset
671 ***********************************************************************
672 */
673 //extern "C"
hal_avsd_vdpu2_reset(void * decoder)674 MPP_RET hal_avsd_vdpu2_reset(void *decoder)
675 {
676 MPP_RET ret = MPP_ERR_UNKNOW;
677 AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
678
679 AVSD_HAL_TRACE("In.");
680
681 p_hal->first_field = 1;
682 p_hal->prev_pic_structure = 0; //!< field
683
684 memset(p_hal->pic, 0, sizeof(p_hal->pic));
685 p_hal->work_out = -1;
686 p_hal->work0 = -1;
687 p_hal->work1 = -1;
688
689 AVSD_HAL_TRACE("Out.");
690
691 return ret = MPP_OK;
692 }
693 /*!
694 ***********************************************************************
695 * \brief
696 * flush
697 ***********************************************************************
698 */
699 //extern "C"
hal_avsd_vdpu2_flush(void * decoder)700 MPP_RET hal_avsd_vdpu2_flush(void *decoder)
701 {
702 MPP_RET ret = MPP_ERR_UNKNOW;
703
704 AVSD_HAL_TRACE("In.");
705
706 (void)decoder;
707
708 AVSD_HAL_TRACE("Out.");
709
710 return ret = MPP_OK;
711 }
712 /*!
713 ***********************************************************************
714 * \brief
715 * control
716 ***********************************************************************
717 */
718 //extern "C"
hal_avsd_vdpu2_control(void * decoder,MpiCmd cmd_type,void * param)719 MPP_RET hal_avsd_vdpu2_control(void *decoder, MpiCmd cmd_type, void *param)
720 {
721 MPP_RET ret = MPP_ERR_UNKNOW;
722
723 AVSD_HAL_TRACE("In.");
724
725 (void)decoder;
726 (void)cmd_type;
727 (void)param;
728
729 AVSD_HAL_TRACE("Out.");
730
731 return ret = MPP_OK;
732 }
733