xref: /rockchip-linux_mpp/mpp/hal/vpu/h263d/hal_h263d_vdpu2.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2016 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_vpu_h263d"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <stdio.h>
20*437bfbebSnyanmisaka #include <string.h>
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #include "mpp_err.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_debug.h"
25*437bfbebSnyanmisaka 
26*437bfbebSnyanmisaka #include "h263d_syntax.h"
27*437bfbebSnyanmisaka #include "hal_h263d_api.h"
28*437bfbebSnyanmisaka #include "hal_h263d_vdpu2.h"
29*437bfbebSnyanmisaka #include "hal_h263d_vdpu2_reg.h"
30*437bfbebSnyanmisaka #include "hal_h263d_base.h"
31*437bfbebSnyanmisaka 
vpu2_h263d_setup_regs_by_syntax(hal_h263_ctx * ctx,MppSyntax syntax)32*437bfbebSnyanmisaka static void vpu2_h263d_setup_regs_by_syntax(hal_h263_ctx *ctx, MppSyntax syntax)
33*437bfbebSnyanmisaka {
34*437bfbebSnyanmisaka     Vpu2H263dRegSet_t *regs = (Vpu2H263dRegSet_t*)ctx->regs;
35*437bfbebSnyanmisaka     DXVA2_DecodeBufferDesc **data = syntax.data;
36*437bfbebSnyanmisaka     DXVA_PicParams_H263 *pp = NULL;
37*437bfbebSnyanmisaka     RK_U32 stream_length = 0;
38*437bfbebSnyanmisaka     RK_U32 stream_used = 0;
39*437bfbebSnyanmisaka     RK_U32 i;
40*437bfbebSnyanmisaka 
41*437bfbebSnyanmisaka     for (i = 0; i < syntax.number; i++) {
42*437bfbebSnyanmisaka         DXVA2_DecodeBufferDesc *desc = data[i];
43*437bfbebSnyanmisaka         switch (desc->CompressedBufferType) {
44*437bfbebSnyanmisaka         case DXVA2_PictureParametersBufferType : {
45*437bfbebSnyanmisaka             pp = (DXVA_PicParams_H263 *)desc->pvPVPState;
46*437bfbebSnyanmisaka         } break;
47*437bfbebSnyanmisaka         case DXVA2_BitStreamDateBufferType : {
48*437bfbebSnyanmisaka             stream_length = desc->DataSize;
49*437bfbebSnyanmisaka             stream_used = desc->DataOffset;
50*437bfbebSnyanmisaka         } break;
51*437bfbebSnyanmisaka         default : {
52*437bfbebSnyanmisaka             mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType);
53*437bfbebSnyanmisaka         } break;
54*437bfbebSnyanmisaka         }
55*437bfbebSnyanmisaka     }
56*437bfbebSnyanmisaka 
57*437bfbebSnyanmisaka     mpp_assert(pp);
58*437bfbebSnyanmisaka     mpp_assert(stream_length);
59*437bfbebSnyanmisaka     mpp_assert(stream_used);
60*437bfbebSnyanmisaka 
61*437bfbebSnyanmisaka     regs->reg120.sw_pic_mb_width = (pp->vop_width  + 15) >> 4;
62*437bfbebSnyanmisaka     regs->reg120.sw_pic_mb_hight_p = (pp->vop_height + 15) >> 4;
63*437bfbebSnyanmisaka     regs->reg120.sw_mb_width_off = pp->vop_width & 0xf;
64*437bfbebSnyanmisaka     regs->reg120.sw_mb_height_off = pp->vop_height & 0xf;
65*437bfbebSnyanmisaka 
66*437bfbebSnyanmisaka     regs->reg53_dec_mode = 2;
67*437bfbebSnyanmisaka     regs->reg50_dec_ctrl.sw_filtering_dis = 1;
68*437bfbebSnyanmisaka     regs->reg136.sw_rounding = 0;
69*437bfbebSnyanmisaka     regs->reg51_stream_info.sw_init_qp = pp->vop_quant;
70*437bfbebSnyanmisaka     regs->reg122.sw_sync_markers_en = 1;
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka     {
73*437bfbebSnyanmisaka         /*
74*437bfbebSnyanmisaka          * update stream base address here according to consumed bit length
75*437bfbebSnyanmisaka          * 1. hardware start address has to be 64 bit align
76*437bfbebSnyanmisaka          * 2. hardware need to know which is the start bit in
77*437bfbebSnyanmisaka          * 2. pass (10bit fd + (offset << 10)) register value to kernel
78*437bfbebSnyanmisaka          */
79*437bfbebSnyanmisaka         RK_U32 val = regs->reg64_input_stream_base;
80*437bfbebSnyanmisaka         RK_U32 consumed_bytes = stream_used >> 3;
81*437bfbebSnyanmisaka         RK_U32 consumed_bytes_align = consumed_bytes & (~0x7);
82*437bfbebSnyanmisaka         RK_U32 start_bit_offset = stream_used & 0x3F;
83*437bfbebSnyanmisaka         RK_U32 left_bytes = stream_length - consumed_bytes_align;
84*437bfbebSnyanmisaka 
85*437bfbebSnyanmisaka         if (consumed_bytes_align) {
86*437bfbebSnyanmisaka             mpp_dev_set_reg_offset(ctx->dev, 64, consumed_bytes_align);
87*437bfbebSnyanmisaka         }
88*437bfbebSnyanmisaka         regs->reg64_input_stream_base = val;
89*437bfbebSnyanmisaka         regs->reg122.sw_stream_start_word = start_bit_offset;
90*437bfbebSnyanmisaka         regs->reg51_stream_info.sw_stream_len = left_bytes;
91*437bfbebSnyanmisaka     }
92*437bfbebSnyanmisaka 
93*437bfbebSnyanmisaka     regs->reg122.sw_vop_time_incr = pp->vop_time_increment_resolution;
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka     switch (pp->vop_coding_type) {
96*437bfbebSnyanmisaka     case H263_P_VOP : {
97*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_inter_e = 1;
98*437bfbebSnyanmisaka 
99*437bfbebSnyanmisaka         if (ctx->fd_ref0 >= 0) {
100*437bfbebSnyanmisaka             regs->reg131_ref0_base = (RK_U32)ctx->fd_ref0;
101*437bfbebSnyanmisaka             regs->reg148_ref1_base = (RK_U32)ctx->fd_ref0;
102*437bfbebSnyanmisaka         } else {
103*437bfbebSnyanmisaka             regs->reg131_ref0_base = (RK_U32)ctx->fd_curr;
104*437bfbebSnyanmisaka             regs->reg148_ref1_base = (RK_U32)ctx->fd_curr;
105*437bfbebSnyanmisaka         }
106*437bfbebSnyanmisaka     } break;
107*437bfbebSnyanmisaka     case H263_I_VOP : {
108*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_inter_e = 0;
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka         regs->reg131_ref0_base = (RK_U32)ctx->fd_curr;
111*437bfbebSnyanmisaka         regs->reg148_ref1_base = (RK_U32)ctx->fd_curr;
112*437bfbebSnyanmisaka     } break;
113*437bfbebSnyanmisaka     default : {
114*437bfbebSnyanmisaka         /* no nothing */
115*437bfbebSnyanmisaka     } break;
116*437bfbebSnyanmisaka     }
117*437bfbebSnyanmisaka 
118*437bfbebSnyanmisaka     regs->reg136.sw_hrz_bit_of_fwd_mv = 1;
119*437bfbebSnyanmisaka     regs->reg136.sw_vrz_bit_of_fwd_mv = 1;
120*437bfbebSnyanmisaka     regs->reg136.sw_prev_pic_type = (pp->prev_coding_type == H263_P_VOP);
121*437bfbebSnyanmisaka }
122*437bfbebSnyanmisaka 
hal_vpu2_h263d_init(void * hal,MppHalCfg * cfg)123*437bfbebSnyanmisaka MPP_RET hal_vpu2_h263d_init(void *hal, MppHalCfg *cfg)
124*437bfbebSnyanmisaka {
125*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
126*437bfbebSnyanmisaka     Vpu2H263dRegSet_t *regs = NULL;
127*437bfbebSnyanmisaka     hal_h263_ctx *ctx = (hal_h263_ctx *)hal;
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     mpp_assert(hal);
130*437bfbebSnyanmisaka 
131*437bfbebSnyanmisaka     regs = mpp_calloc(Vpu2H263dRegSet_t, 1);
132*437bfbebSnyanmisaka     if (NULL == regs) {
133*437bfbebSnyanmisaka         mpp_err_f("failed to malloc register ret\n");
134*437bfbebSnyanmisaka         ret = MPP_ERR_MALLOC;
135*437bfbebSnyanmisaka         goto ERR_RET;
136*437bfbebSnyanmisaka     }
137*437bfbebSnyanmisaka 
138*437bfbebSnyanmisaka     ret = mpp_dev_init(&ctx->dev, VPU_CLIENT_VDPU2);
139*437bfbebSnyanmisaka     if (ret) {
140*437bfbebSnyanmisaka         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
141*437bfbebSnyanmisaka         ret = MPP_ERR_UNKNOW;
142*437bfbebSnyanmisaka         goto ERR_RET;
143*437bfbebSnyanmisaka     }
144*437bfbebSnyanmisaka 
145*437bfbebSnyanmisaka     ctx->frm_slots  = cfg->frame_slots;
146*437bfbebSnyanmisaka     ctx->pkt_slots  = cfg->packet_slots;
147*437bfbebSnyanmisaka     ctx->dec_cb     = cfg->dec_cb;
148*437bfbebSnyanmisaka     ctx->regs       = (void*)regs;
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka     return ret;
151*437bfbebSnyanmisaka ERR_RET:
152*437bfbebSnyanmisaka     if (regs) {
153*437bfbebSnyanmisaka         mpp_free(regs);
154*437bfbebSnyanmisaka         regs = NULL;
155*437bfbebSnyanmisaka     }
156*437bfbebSnyanmisaka 
157*437bfbebSnyanmisaka     return ret;
158*437bfbebSnyanmisaka }
159*437bfbebSnyanmisaka 
hal_vpu2_h263d_deinit(void * hal)160*437bfbebSnyanmisaka MPP_RET hal_vpu2_h263d_deinit(void *hal)
161*437bfbebSnyanmisaka {
162*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
163*437bfbebSnyanmisaka     hal_h263_ctx *ctx = (hal_h263_ctx *)hal;
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka     mpp_assert(hal);
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka     if (ctx->regs) {
168*437bfbebSnyanmisaka         mpp_free(ctx->regs);
169*437bfbebSnyanmisaka         ctx->regs = NULL;
170*437bfbebSnyanmisaka     }
171*437bfbebSnyanmisaka 
172*437bfbebSnyanmisaka     if (ctx->dev) {
173*437bfbebSnyanmisaka         mpp_dev_deinit(ctx->dev);
174*437bfbebSnyanmisaka         ctx->dev = NULL;
175*437bfbebSnyanmisaka     }
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka     return ret;
178*437bfbebSnyanmisaka }
179*437bfbebSnyanmisaka 
hal_vpu2_h263d_gen_regs(void * hal,HalTaskInfo * syn)180*437bfbebSnyanmisaka MPP_RET hal_vpu2_h263d_gen_regs(void *hal,  HalTaskInfo *syn)
181*437bfbebSnyanmisaka {
182*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
183*437bfbebSnyanmisaka     hal_h263_ctx *ctx = (hal_h263_ctx *)hal;
184*437bfbebSnyanmisaka     HalDecTask *task = &syn->dec;
185*437bfbebSnyanmisaka     MppBuffer buf_frm_curr = NULL;
186*437bfbebSnyanmisaka     MppBuffer buf_frm_ref0 = NULL;
187*437bfbebSnyanmisaka     MppBuffer buf_pkt = NULL;
188*437bfbebSnyanmisaka     Vpu2H263dRegSet_t *regs = (Vpu2H263dRegSet_t*)ctx->regs;
189*437bfbebSnyanmisaka 
190*437bfbebSnyanmisaka     mpp_assert(task->valid);
191*437bfbebSnyanmisaka     mpp_assert(task->input >= 0);
192*437bfbebSnyanmisaka     mpp_assert(task->output >= 0);
193*437bfbebSnyanmisaka 
194*437bfbebSnyanmisaka     memset(regs, 0, sizeof(Vpu2H263dRegSet_t));
195*437bfbebSnyanmisaka 
196*437bfbebSnyanmisaka     /*
197*437bfbebSnyanmisaka      * basic register configuration setup here
198*437bfbebSnyanmisaka      */
199*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_out_endian = 1;
200*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_in_endian = 1;
201*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_inswap32_e = 1;
202*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_outswap32_e = 1;
203*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_strswap32_e = 1;
204*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_strendian_e = 1;
205*437bfbebSnyanmisaka     regs->reg56_axi_ctrl.sw_dec_max_burst = 16;
206*437bfbebSnyanmisaka     regs->reg52_error_concealment.sw_apf_threshold = 1;
207*437bfbebSnyanmisaka     regs->reg57_enable_ctrl.sw_dec_timeout_e = 1;
208*437bfbebSnyanmisaka     regs->reg57_enable_ctrl.sw_dec_clk_gate_e = 1;
209*437bfbebSnyanmisaka     regs->reg57_enable_ctrl.sw_dec_e = 1;
210*437bfbebSnyanmisaka     regs->reg59.sw_pred_bc_tap_0_0 = -1;
211*437bfbebSnyanmisaka     regs->reg59.sw_pred_bc_tap_0_1 = 3;
212*437bfbebSnyanmisaka     regs->reg59.sw_pred_bc_tap_0_2 = -6;
213*437bfbebSnyanmisaka     regs->reg153.sw_pred_bc_tap_0_3 = 20;
214*437bfbebSnyanmisaka 
215*437bfbebSnyanmisaka     /* setup buffer for input / output / reference */
216*437bfbebSnyanmisaka     mpp_buf_slot_get_prop(ctx->pkt_slots, task->input, SLOT_BUFFER, &buf_pkt);
217*437bfbebSnyanmisaka     mpp_assert(buf_pkt);
218*437bfbebSnyanmisaka     vpu_h263d_get_buffer_by_index(ctx, task->output, &buf_frm_curr);
219*437bfbebSnyanmisaka     vpu_h263d_get_buffer_by_index(ctx, task->refer[0], &buf_frm_ref0);
220*437bfbebSnyanmisaka 
221*437bfbebSnyanmisaka     /* address registers setup first */
222*437bfbebSnyanmisaka     ctx->fd_curr = mpp_buffer_get_fd(buf_frm_curr);
223*437bfbebSnyanmisaka     ctx->fd_ref0 = (buf_frm_ref0) ? (mpp_buffer_get_fd(buf_frm_ref0)) : (-1);
224*437bfbebSnyanmisaka     regs->reg63_cur_pic_base = (RK_U32)ctx->fd_curr;
225*437bfbebSnyanmisaka     regs->reg64_input_stream_base = mpp_buffer_get_fd(buf_pkt);
226*437bfbebSnyanmisaka 
227*437bfbebSnyanmisaka     /* setup other registers, here will update packet address */
228*437bfbebSnyanmisaka     vpu2_h263d_setup_regs_by_syntax(ctx, task->syntax);
229*437bfbebSnyanmisaka 
230*437bfbebSnyanmisaka     return ret;
231*437bfbebSnyanmisaka }
232*437bfbebSnyanmisaka 
hal_vpu2_h263d_start(void * hal,HalTaskInfo * task)233*437bfbebSnyanmisaka MPP_RET hal_vpu2_h263d_start(void *hal, HalTaskInfo *task)
234*437bfbebSnyanmisaka {
235*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
236*437bfbebSnyanmisaka     hal_h263_ctx *ctx = (hal_h263_ctx *)hal;
237*437bfbebSnyanmisaka     RK_U32 *regs = (RK_U32 *)ctx->regs;
238*437bfbebSnyanmisaka 
239*437bfbebSnyanmisaka     if (h263d_hal_debug & H263D_HAL_DBG_REG_PUT) {
240*437bfbebSnyanmisaka         RK_U32 reg_count = (sizeof(Vpu2H263dRegSet_t) / sizeof(RK_U32));
241*437bfbebSnyanmisaka         RK_U32 i = 0;
242*437bfbebSnyanmisaka 
243*437bfbebSnyanmisaka         for (i = 0; i < reg_count; i++)
244*437bfbebSnyanmisaka             mpp_log("reg[%03d]: %08x\n", i, regs[i]);
245*437bfbebSnyanmisaka     }
246*437bfbebSnyanmisaka 
247*437bfbebSnyanmisaka     do {
248*437bfbebSnyanmisaka         MppDevRegWrCfg wr_cfg;
249*437bfbebSnyanmisaka         MppDevRegRdCfg rd_cfg;
250*437bfbebSnyanmisaka 
251*437bfbebSnyanmisaka         wr_cfg.reg = regs;
252*437bfbebSnyanmisaka         wr_cfg.size = sizeof(Vpu2H263dRegSet_t);
253*437bfbebSnyanmisaka         wr_cfg.offset = 0;
254*437bfbebSnyanmisaka 
255*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
256*437bfbebSnyanmisaka         if (ret) {
257*437bfbebSnyanmisaka             mpp_err_f("set register write failed %d\n", ret);
258*437bfbebSnyanmisaka             break;
259*437bfbebSnyanmisaka         }
260*437bfbebSnyanmisaka 
261*437bfbebSnyanmisaka         rd_cfg.reg = regs;
262*437bfbebSnyanmisaka         rd_cfg.size = sizeof(Vpu2H263dRegSet_t);
263*437bfbebSnyanmisaka         rd_cfg.offset = 0;
264*437bfbebSnyanmisaka 
265*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
266*437bfbebSnyanmisaka         if (ret) {
267*437bfbebSnyanmisaka             mpp_err_f("set register read failed %d\n", ret);
268*437bfbebSnyanmisaka             break;
269*437bfbebSnyanmisaka         }
270*437bfbebSnyanmisaka 
271*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
272*437bfbebSnyanmisaka         if (ret) {
273*437bfbebSnyanmisaka             mpp_err_f("send cmd failed %d\n", ret);
274*437bfbebSnyanmisaka             break;
275*437bfbebSnyanmisaka         }
276*437bfbebSnyanmisaka     } while (0);
277*437bfbebSnyanmisaka 
278*437bfbebSnyanmisaka     (void)task;
279*437bfbebSnyanmisaka     return ret;
280*437bfbebSnyanmisaka }
281*437bfbebSnyanmisaka 
hal_vpu2_h263d_wait(void * hal,HalTaskInfo * task)282*437bfbebSnyanmisaka MPP_RET hal_vpu2_h263d_wait(void *hal, HalTaskInfo *task)
283*437bfbebSnyanmisaka {
284*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
285*437bfbebSnyanmisaka     hal_h263_ctx *ctx = (hal_h263_ctx *)hal;
286*437bfbebSnyanmisaka 
287*437bfbebSnyanmisaka     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
288*437bfbebSnyanmisaka     if (ret)
289*437bfbebSnyanmisaka         mpp_err_f("poll cmd failed %d\n", ret);
290*437bfbebSnyanmisaka 
291*437bfbebSnyanmisaka     if (h263d_hal_debug & H263D_HAL_DBG_REG_GET) {
292*437bfbebSnyanmisaka         RK_U32 *regs = (RK_U32 *)ctx->regs;
293*437bfbebSnyanmisaka         RK_U32 reg_count = (sizeof(Vpu2H263dRegSet_t) / sizeof(RK_U32));
294*437bfbebSnyanmisaka         RK_U32 i = 0;
295*437bfbebSnyanmisaka 
296*437bfbebSnyanmisaka         for (i = 0; i < reg_count; i++)
297*437bfbebSnyanmisaka             mpp_log("reg[%03d]: %08x\n", i, regs[i]);
298*437bfbebSnyanmisaka     }
299*437bfbebSnyanmisaka 
300*437bfbebSnyanmisaka     (void)task;
301*437bfbebSnyanmisaka     return ret;
302*437bfbebSnyanmisaka }
303