xref: /rockchip-linux_mpp/mpp/hal/rkdec/vdpu34x_com.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2020 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 "vdpu34x_com"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka #include <stdlib.h>
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #include "mpp_log.h"
23*437bfbebSnyanmisaka #include "mpp_buffer.h"
24*437bfbebSnyanmisaka #include "mpp_common.h"
25*437bfbebSnyanmisaka #include "mpp_compat_impl.h"
26*437bfbebSnyanmisaka #include "mpp_env.h"
27*437bfbebSnyanmisaka 
28*437bfbebSnyanmisaka #include "vdpu34x_com.h"
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka static RK_U32 rcb_coeff[RCB_BUF_COUNT] = {
31*437bfbebSnyanmisaka     [RCB_INTRA_ROW]     = 6,   /* RCB_INTRA_ROW_COEF */
32*437bfbebSnyanmisaka     [RCB_TRANSD_ROW]    = 1,   /* RCB_TRANSD_ROW_COEF */
33*437bfbebSnyanmisaka     [RCB_TRANSD_COL]    = 1,   /* RCB_TRANSD_COL_COEF */
34*437bfbebSnyanmisaka     [RCB_STRMD_ROW]     = 3,   /* RCB_STRMD_ROW_COEF */
35*437bfbebSnyanmisaka     [RCB_INTER_ROW]     = 6,   /* RCB_INTER_ROW_COEF */
36*437bfbebSnyanmisaka     [RCB_INTER_COL]     = 3,   /* RCB_INTER_COL_COEF */
37*437bfbebSnyanmisaka     [RCB_DBLK_ROW]      = 22,  /* RCB_DBLK_ROW_COEF */
38*437bfbebSnyanmisaka     [RCB_SAO_ROW]       = 6,   /* RCB_SAO_ROW_COEF */
39*437bfbebSnyanmisaka     [RCB_FBC_ROW]       = 11,  /* RCB_FBC_ROW_COEF */
40*437bfbebSnyanmisaka     [RCB_FILT_COL]      = 67,  /* RCB_FILT_COL_COEF */
41*437bfbebSnyanmisaka };
42*437bfbebSnyanmisaka 
update_size_offset(Vdpu34xRcbInfo * info,RK_U32 reg,RK_S32 offset,RK_S32 len,RK_S32 idx)43*437bfbebSnyanmisaka static RK_S32 update_size_offset(Vdpu34xRcbInfo *info, RK_U32 reg,
44*437bfbebSnyanmisaka                                  RK_S32 offset, RK_S32 len, RK_S32 idx)
45*437bfbebSnyanmisaka {
46*437bfbebSnyanmisaka     RK_S32 buf_size = 0;
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka     buf_size = MPP_ALIGN(len * rcb_coeff[idx], RCB_ALLINE_SIZE);
49*437bfbebSnyanmisaka     info[idx].reg = reg;
50*437bfbebSnyanmisaka     info[idx].offset = offset;
51*437bfbebSnyanmisaka     info[idx].size = buf_size;
52*437bfbebSnyanmisaka 
53*437bfbebSnyanmisaka     return buf_size;
54*437bfbebSnyanmisaka }
55*437bfbebSnyanmisaka 
vdpu34x_get_rcb_buf_size(Vdpu34xRcbInfo * info,RK_S32 width,RK_S32 height)56*437bfbebSnyanmisaka RK_S32 vdpu34x_get_rcb_buf_size(Vdpu34xRcbInfo *info, RK_S32 width, RK_S32 height)
57*437bfbebSnyanmisaka {
58*437bfbebSnyanmisaka     RK_S32 offset = 0;
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka     offset += update_size_offset(info, 139, offset, width, RCB_DBLK_ROW);
61*437bfbebSnyanmisaka     offset += update_size_offset(info, 133, offset, width, RCB_INTRA_ROW);
62*437bfbebSnyanmisaka     offset += update_size_offset(info, 134, offset, width, RCB_TRANSD_ROW);
63*437bfbebSnyanmisaka     offset += update_size_offset(info, 136, offset, width, RCB_STRMD_ROW);
64*437bfbebSnyanmisaka     offset += update_size_offset(info, 137, offset, width, RCB_INTER_ROW);
65*437bfbebSnyanmisaka     offset += update_size_offset(info, 140, offset, width, RCB_SAO_ROW);
66*437bfbebSnyanmisaka     offset += update_size_offset(info, 141, offset, width, RCB_FBC_ROW);
67*437bfbebSnyanmisaka     /* col rcb */
68*437bfbebSnyanmisaka     offset += update_size_offset(info, 135, offset, height, RCB_TRANSD_COL);
69*437bfbebSnyanmisaka     offset += update_size_offset(info, 138, offset, height, RCB_INTER_COL);
70*437bfbebSnyanmisaka     offset += update_size_offset(info, 142, offset, height, RCB_FILT_COL);
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka     return offset;
73*437bfbebSnyanmisaka }
74*437bfbebSnyanmisaka 
vdpu34x_setup_rcb(Vdpu34xRegCommonAddr * reg,MppDev dev,MppBuffer buf,Vdpu34xRcbInfo * info)75*437bfbebSnyanmisaka void vdpu34x_setup_rcb(Vdpu34xRegCommonAddr *reg, MppDev dev, MppBuffer buf, Vdpu34xRcbInfo *info)
76*437bfbebSnyanmisaka {
77*437bfbebSnyanmisaka     RK_S32 fd = mpp_buffer_get_fd(buf);
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka     reg->reg139_rcb_dblk_base           = fd;
80*437bfbebSnyanmisaka     reg->reg133_rcb_intra_base          = fd;
81*437bfbebSnyanmisaka     reg->reg134_rcb_transd_row_base     = fd;
82*437bfbebSnyanmisaka     reg->reg136_rcb_streamd_row_base    = fd;
83*437bfbebSnyanmisaka     reg->reg137_rcb_inter_row_base      = fd;
84*437bfbebSnyanmisaka     reg->reg140_rcb_sao_base            = fd;
85*437bfbebSnyanmisaka     reg->reg141_rcb_fbc_base            = fd;
86*437bfbebSnyanmisaka     reg->reg135_rcb_transd_col_base     = fd;
87*437bfbebSnyanmisaka     reg->reg138_rcb_inter_col_base      = fd;
88*437bfbebSnyanmisaka     reg->reg142_rcb_filter_col_base     = fd;
89*437bfbebSnyanmisaka 
90*437bfbebSnyanmisaka     if (info[RCB_DBLK_ROW].offset)
91*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 139, info[RCB_DBLK_ROW].offset);
92*437bfbebSnyanmisaka     if (info[RCB_INTRA_ROW].offset)
93*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 133, info[RCB_INTRA_ROW].offset);
94*437bfbebSnyanmisaka     if (info[RCB_TRANSD_ROW].offset)
95*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 134, info[RCB_TRANSD_ROW].offset);
96*437bfbebSnyanmisaka     if (info[RCB_STRMD_ROW].offset)
97*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 136, info[RCB_STRMD_ROW].offset);
98*437bfbebSnyanmisaka     if (info[RCB_INTER_ROW].offset)
99*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 137, info[RCB_INTER_ROW].offset);
100*437bfbebSnyanmisaka     if (info[RCB_SAO_ROW].offset)
101*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 140, info[RCB_SAO_ROW].offset);
102*437bfbebSnyanmisaka     if (info[RCB_FBC_ROW].offset)
103*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 141, info[RCB_FBC_ROW].offset);
104*437bfbebSnyanmisaka     if (info[RCB_TRANSD_COL].offset)
105*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 135, info[RCB_TRANSD_COL].offset);
106*437bfbebSnyanmisaka     if (info[RCB_INTER_COL].offset)
107*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 138, info[RCB_INTER_COL].offset);
108*437bfbebSnyanmisaka     if (info[RCB_FILT_COL].offset)
109*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 142, info[RCB_FILT_COL].offset);
110*437bfbebSnyanmisaka }
111*437bfbebSnyanmisaka 
vdpu34x_compare_rcb_size(const void * a,const void * b)112*437bfbebSnyanmisaka static RK_S32 vdpu34x_compare_rcb_size(const void *a, const void *b)
113*437bfbebSnyanmisaka {
114*437bfbebSnyanmisaka     Vdpu34xRcbInfo *p0 = (Vdpu34xRcbInfo *)a;
115*437bfbebSnyanmisaka     Vdpu34xRcbInfo *p1 = (Vdpu34xRcbInfo *)b;
116*437bfbebSnyanmisaka 
117*437bfbebSnyanmisaka     return (p0->size > p1->size) ? -1 : 1;
118*437bfbebSnyanmisaka }
119*437bfbebSnyanmisaka 
vdpu34x_set_rcbinfo(MppDev dev,Vdpu34xRcbInfo * rcb_info)120*437bfbebSnyanmisaka RK_S32 vdpu34x_set_rcbinfo(MppDev dev, Vdpu34xRcbInfo *rcb_info)
121*437bfbebSnyanmisaka {
122*437bfbebSnyanmisaka     MppDevRcbInfoCfg rcb_cfg;
123*437bfbebSnyanmisaka     RK_U32 i;
124*437bfbebSnyanmisaka     /*
125*437bfbebSnyanmisaka      * RCB_SET_BY_SIZE_SORT_MODE: by size sort
126*437bfbebSnyanmisaka      * RCB_SET_BY_PRIORITY_MODE: by priority
127*437bfbebSnyanmisaka      */
128*437bfbebSnyanmisaka     Vdpu34xRcbSetMode_e set_rcb_mode = RCB_SET_BY_PRIORITY_MODE;
129*437bfbebSnyanmisaka     RK_U32 rcb_priority[RCB_BUF_COUNT] = {
130*437bfbebSnyanmisaka         RCB_DBLK_ROW,
131*437bfbebSnyanmisaka         RCB_INTRA_ROW,
132*437bfbebSnyanmisaka         RCB_SAO_ROW,
133*437bfbebSnyanmisaka         RCB_INTER_ROW,
134*437bfbebSnyanmisaka         RCB_FBC_ROW,
135*437bfbebSnyanmisaka         RCB_TRANSD_ROW,
136*437bfbebSnyanmisaka         RCB_STRMD_ROW,
137*437bfbebSnyanmisaka         RCB_INTER_COL,
138*437bfbebSnyanmisaka         RCB_FILT_COL,
139*437bfbebSnyanmisaka         RCB_TRANSD_COL,
140*437bfbebSnyanmisaka     };
141*437bfbebSnyanmisaka 
142*437bfbebSnyanmisaka     switch (set_rcb_mode) {
143*437bfbebSnyanmisaka     case RCB_SET_BY_SIZE_SORT_MODE : {
144*437bfbebSnyanmisaka         Vdpu34xRcbInfo info[RCB_BUF_COUNT];
145*437bfbebSnyanmisaka 
146*437bfbebSnyanmisaka         memcpy(info, rcb_info, sizeof(info));
147*437bfbebSnyanmisaka         qsort(info, MPP_ARRAY_ELEMS(info),
148*437bfbebSnyanmisaka               sizeof(info[0]), vdpu34x_compare_rcb_size);
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka         for (i = 0; i < MPP_ARRAY_ELEMS(info); i++) {
151*437bfbebSnyanmisaka             rcb_cfg.reg_idx = info[i].reg;
152*437bfbebSnyanmisaka             rcb_cfg.size = info[i].size;
153*437bfbebSnyanmisaka             if (rcb_cfg.size > 0) {
154*437bfbebSnyanmisaka                 mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg);
155*437bfbebSnyanmisaka             } else
156*437bfbebSnyanmisaka                 break;
157*437bfbebSnyanmisaka         }
158*437bfbebSnyanmisaka     } break;
159*437bfbebSnyanmisaka     case RCB_SET_BY_PRIORITY_MODE : {
160*437bfbebSnyanmisaka         Vdpu34xRcbInfo *info = rcb_info;
161*437bfbebSnyanmisaka         RK_U32 index = 0;
162*437bfbebSnyanmisaka 
163*437bfbebSnyanmisaka         for (i = 0; i < MPP_ARRAY_ELEMS(rcb_priority); i ++) {
164*437bfbebSnyanmisaka             index = rcb_priority[i];
165*437bfbebSnyanmisaka             /*
166*437bfbebSnyanmisaka              * If the inter row rcb buffer is placed in sram,
167*437bfbebSnyanmisaka              * may conflict with other buffer in ddr,
168*437bfbebSnyanmisaka              * will result in slower access to data and degraded decoding performance.
169*437bfbebSnyanmisaka              * The issue will be resolved in chips after rk3588.
170*437bfbebSnyanmisaka              */
171*437bfbebSnyanmisaka             if (index == RCB_INTER_ROW)
172*437bfbebSnyanmisaka                 continue;
173*437bfbebSnyanmisaka 
174*437bfbebSnyanmisaka             rcb_cfg.reg_idx = info[index].reg;
175*437bfbebSnyanmisaka             rcb_cfg.size = info[index].size;
176*437bfbebSnyanmisaka             if (rcb_cfg.size > 0) {
177*437bfbebSnyanmisaka                 mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg);
178*437bfbebSnyanmisaka             }
179*437bfbebSnyanmisaka         }
180*437bfbebSnyanmisaka     } break;
181*437bfbebSnyanmisaka     default:
182*437bfbebSnyanmisaka         break;
183*437bfbebSnyanmisaka     }
184*437bfbebSnyanmisaka 
185*437bfbebSnyanmisaka     return 0;
186*437bfbebSnyanmisaka }
187*437bfbebSnyanmisaka 
vdpu34x_setup_statistic(Vdpu34xRegCommon * com,Vdpu34xRegStatistic * sta)188*437bfbebSnyanmisaka void vdpu34x_setup_statistic(Vdpu34xRegCommon *com, Vdpu34xRegStatistic *sta)
189*437bfbebSnyanmisaka {
190*437bfbebSnyanmisaka     com->reg011.pix_range_detection_e = 1;
191*437bfbebSnyanmisaka 
192*437bfbebSnyanmisaka     memset(sta, 0, sizeof(*sta));
193*437bfbebSnyanmisaka 
194*437bfbebSnyanmisaka     sta->reg256.axi_perf_work_e = 1;
195*437bfbebSnyanmisaka     sta->reg256.axi_perf_clr_e = 1;
196*437bfbebSnyanmisaka     sta->reg256.axi_cnt_type = 1;
197*437bfbebSnyanmisaka 
198*437bfbebSnyanmisaka     sta->reg257.addr_align_type = 1;
199*437bfbebSnyanmisaka 
200*437bfbebSnyanmisaka     /* set hurry */
201*437bfbebSnyanmisaka     sta->reg270.axi_rd_hurry_level = 3;
202*437bfbebSnyanmisaka     sta->reg270.axi_wr_hurry_level = 1;
203*437bfbebSnyanmisaka     sta->reg270.axi_wr_qos = 1;
204*437bfbebSnyanmisaka     sta->reg270.axi_rd_qos = 3;
205*437bfbebSnyanmisaka     sta->reg270.bus2mc_buffer_qos_level = 255;
206*437bfbebSnyanmisaka     sta->reg271_wr_wait_cycle_qos = 0;
207*437bfbebSnyanmisaka }
208*437bfbebSnyanmisaka 
vdpu34x_afbc_align_calc(MppBufSlots slots,MppFrame frame,RK_U32 expand)209*437bfbebSnyanmisaka void vdpu34x_afbc_align_calc(MppBufSlots slots, MppFrame frame, RK_U32 expand)
210*437bfbebSnyanmisaka {
211*437bfbebSnyanmisaka     RK_U32 ver_stride = 0;
212*437bfbebSnyanmisaka     RK_U32 img_height = mpp_frame_get_height(frame);
213*437bfbebSnyanmisaka     RK_U32 img_width = mpp_frame_get_width(frame);
214*437bfbebSnyanmisaka     RK_U32 hdr_stride = (*compat_ext_fbc_hdr_256_odd) ?
215*437bfbebSnyanmisaka                         (MPP_ALIGN(img_width, 256) | 256) :
216*437bfbebSnyanmisaka                         (MPP_ALIGN(img_width, 64));
217*437bfbebSnyanmisaka 
218*437bfbebSnyanmisaka     mpp_slots_set_prop(slots, SLOTS_HOR_ALIGN, mpp_align_64);
219*437bfbebSnyanmisaka     mpp_slots_set_prop(slots, SLOTS_VER_ALIGN, mpp_align_16);
220*437bfbebSnyanmisaka 
221*437bfbebSnyanmisaka     mpp_frame_set_fbc_hdr_stride(frame, hdr_stride);
222*437bfbebSnyanmisaka 
223*437bfbebSnyanmisaka     ver_stride = mpp_align_16(img_height);
224*437bfbebSnyanmisaka     if (*compat_ext_fbc_buf_size) {
225*437bfbebSnyanmisaka         ver_stride += expand;
226*437bfbebSnyanmisaka     }
227*437bfbebSnyanmisaka     mpp_frame_set_ver_stride(frame, ver_stride);
228*437bfbebSnyanmisaka }
229*437bfbebSnyanmisaka 
vdpu34x_get_colmv_size(RK_U32 width,RK_U32 height,RK_U32 ctu_size,RK_U32 colmv_bytes,RK_U32 colmv_size,RK_U32 compress)230*437bfbebSnyanmisaka RK_U32 vdpu34x_get_colmv_size(RK_U32 width, RK_U32 height, RK_U32 ctu_size,
231*437bfbebSnyanmisaka                               RK_U32 colmv_bytes, RK_U32 colmv_size, RK_U32 compress)
232*437bfbebSnyanmisaka {
233*437bfbebSnyanmisaka     RK_U32 colmv_total_size;
234*437bfbebSnyanmisaka 
235*437bfbebSnyanmisaka     if (compress) {
236*437bfbebSnyanmisaka         RK_U32 segment_w = (64 * colmv_size * colmv_size) / ctu_size;
237*437bfbebSnyanmisaka         RK_U32 segment_h = ctu_size;
238*437bfbebSnyanmisaka         RK_U32 seg_cnt_w = MPP_ALIGN(width, segment_w) / segment_w;
239*437bfbebSnyanmisaka         RK_U32 seg_cnt_h = MPP_ALIGN(height, segment_h) / segment_h;
240*437bfbebSnyanmisaka         RK_U32 seg_head_size = MPP_ALIGN(seg_cnt_w, 16) * seg_cnt_h;
241*437bfbebSnyanmisaka         RK_U32 seg_payload_size = seg_cnt_w * seg_cnt_h * 64 * colmv_bytes;
242*437bfbebSnyanmisaka 
243*437bfbebSnyanmisaka         colmv_total_size = seg_head_size + seg_payload_size;
244*437bfbebSnyanmisaka     } else {
245*437bfbebSnyanmisaka         RK_U32 colmv_block_size_w = MPP_ALIGN(width, 64) / colmv_size;
246*437bfbebSnyanmisaka         RK_U32 colmv_block_size_h = MPP_ALIGN(height, 64) / colmv_size;
247*437bfbebSnyanmisaka 
248*437bfbebSnyanmisaka         colmv_total_size = colmv_block_size_w * colmv_block_size_h * colmv_bytes;
249*437bfbebSnyanmisaka     }
250*437bfbebSnyanmisaka 
251*437bfbebSnyanmisaka     return MPP_ALIGN(colmv_total_size, 128);
252*437bfbebSnyanmisaka }
253