xref: /OK3568_Linux_fs/external/mpp/mpp/hal/rkdec/vdpu382_com.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2022 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 "vdpu382_com"
18 
19 #include <string.h>
20 #include <stdlib.h>
21 #include "mpp_log.h"
22 #include "mpp_buffer.h"
23 #include "mpp_common.h"
24 #include "mpp_compat_impl.h"
25 #include "mpp_frame_impl.h"
26 #include "mpp_env.h"
27 
28 #include "vdpu382_com.h"
29 
30 static RK_U32 rcb_coeff[RCB_BUF_COUNT] = {
31     [RCB_INTRA_ROW]     = 6,   /* RCB_INTRA_ROW_COEF */
32     [RCB_TRANSD_ROW]    = 1,   /* RCB_TRANSD_ROW_COEF */
33     [RCB_TRANSD_COL]    = 1,   /* RCB_TRANSD_COL_COEF */
34     [RCB_STRMD_ROW]     = 3,   /* RCB_STRMD_ROW_COEF */
35     [RCB_INTER_ROW]     = 6,   /* RCB_INTER_ROW_COEF */
36     [RCB_INTER_COL]     = 3,   /* RCB_INTER_COL_COEF */
37     [RCB_DBLK_ROW]      = 22,  /* RCB_DBLK_ROW_COEF */
38     [RCB_SAO_ROW]       = 6,   /* RCB_SAO_ROW_COEF */
39     [RCB_FBC_ROW]       = 11,  /* RCB_FBC_ROW_COEF */
40     [RCB_FILT_COL]      = 67,  /* RCB_FILT_COL_COEF */
41 };
42 
update_size_offset(Vdpu382RcbInfo * info,RK_U32 reg,RK_S32 offset,RK_S32 len,RK_S32 idx)43 static RK_S32 update_size_offset(Vdpu382RcbInfo *info, RK_U32 reg,
44                                  RK_S32 offset, RK_S32 len, RK_S32 idx)
45 {
46     RK_S32 buf_size = 0;
47 
48     buf_size = MPP_ALIGN(len * rcb_coeff[idx], RCB_ALLINE_SIZE);
49     info[idx].reg = reg;
50     info[idx].offset = offset;
51     info[idx].size = buf_size;
52 
53     return buf_size;
54 }
55 
vdpu382_get_rcb_buf_size(Vdpu382RcbInfo * info,RK_S32 width,RK_S32 height)56 RK_S32 vdpu382_get_rcb_buf_size(Vdpu382RcbInfo *info, RK_S32 width, RK_S32 height)
57 {
58     RK_S32 offset = 0;
59 
60     offset += update_size_offset(info, 139, offset, width, RCB_DBLK_ROW);
61     offset += update_size_offset(info, 133, offset, width, RCB_INTRA_ROW);
62     offset += update_size_offset(info, 134, offset, width, RCB_TRANSD_ROW);
63     offset += update_size_offset(info, 136, offset, width, RCB_STRMD_ROW);
64     offset += update_size_offset(info, 137, offset, width, RCB_INTER_ROW);
65     offset += update_size_offset(info, 140, offset, width, RCB_SAO_ROW);
66     offset += update_size_offset(info, 141, offset, width, RCB_FBC_ROW);
67     /* col rcb */
68     offset += update_size_offset(info, 135, offset, height, RCB_TRANSD_COL);
69     offset += update_size_offset(info, 138, offset, height, RCB_INTER_COL);
70     offset += update_size_offset(info, 142, offset, height, RCB_FILT_COL);
71 
72     return offset;
73 }
74 
vdpu382_setup_rcb(Vdpu382RegCommonAddr * reg,MppDev dev,MppBuffer buf,Vdpu382RcbInfo * info)75 void vdpu382_setup_rcb(Vdpu382RegCommonAddr *reg, MppDev dev, MppBuffer buf, Vdpu382RcbInfo *info)
76 {
77     MppDevRegOffsetCfg trans_cfg;
78     RK_S32 fd = mpp_buffer_get_fd(buf);
79 
80     reg->reg139_rcb_dblk_base           = fd;
81     reg->reg133_rcb_intra_base          = fd;
82     reg->reg134_rcb_transd_row_base     = fd;
83     reg->reg136_rcb_streamd_row_base    = fd;
84     reg->reg137_rcb_inter_row_base      = fd;
85     reg->reg140_rcb_sao_base            = fd;
86     reg->reg141_rcb_fbc_base            = fd;
87     reg->reg135_rcb_transd_col_base     = fd;
88     reg->reg138_rcb_inter_col_base      = fd;
89     reg->reg142_rcb_filter_col_base     = fd;
90 
91     if (info[RCB_DBLK_ROW].offset) {
92         trans_cfg.reg_idx = 139;
93         trans_cfg.offset = info[RCB_DBLK_ROW].offset;
94         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
95     }
96 
97     if (info[RCB_INTRA_ROW].offset) {
98         trans_cfg.reg_idx = 133;
99         trans_cfg.offset = info[RCB_INTRA_ROW].offset;
100         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
101     }
102 
103     if (info[RCB_TRANSD_ROW].offset) {
104         trans_cfg.reg_idx = 134;
105         trans_cfg.offset = info[RCB_TRANSD_ROW].offset;
106         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
107     }
108 
109     if (info[RCB_STRMD_ROW].offset) {
110         trans_cfg.reg_idx = 136;
111         trans_cfg.offset = info[RCB_STRMD_ROW].offset;
112         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
113     }
114 
115     if (info[RCB_INTER_ROW].offset) {
116         trans_cfg.reg_idx = 137;
117         trans_cfg.offset = info[RCB_INTER_ROW].offset;
118         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
119     }
120 
121     if (info[RCB_SAO_ROW].offset) {
122         trans_cfg.reg_idx = 140;
123         trans_cfg.offset = info[RCB_SAO_ROW].offset;
124         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
125     }
126 
127     if (info[RCB_FBC_ROW].offset) {
128         trans_cfg.reg_idx = 141;
129         trans_cfg.offset = info[RCB_FBC_ROW].offset;
130         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
131     }
132 
133     if (info[RCB_TRANSD_COL].offset) {
134         trans_cfg.reg_idx = 135;
135         trans_cfg.offset = info[RCB_TRANSD_COL].offset;
136         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
137     }
138 
139     if (info[RCB_INTER_COL].offset) {
140         trans_cfg.reg_idx = 138;
141         trans_cfg.offset = info[RCB_INTER_COL].offset;
142         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
143     }
144 
145     if (info[RCB_FILT_COL].offset) {
146         trans_cfg.reg_idx = 142;
147         trans_cfg.offset = info[RCB_FILT_COL].offset;
148         mpp_dev_ioctl(dev, MPP_DEV_REG_OFFSET, &trans_cfg);
149     }
150 }
151 
vdpu382_compare_rcb_size(const void * a,const void * b)152 RK_S32 vdpu382_compare_rcb_size(const void *a, const void *b)
153 {
154     RK_S32 val = 0;
155     Vdpu382RcbInfo *p0 = (Vdpu382RcbInfo *)a;
156     Vdpu382RcbInfo *p1 = (Vdpu382RcbInfo *)b;
157 
158     val = (p0->size > p1->size) ? -1 : 1;
159 
160     return val;
161 }
162 
vdpu382_set_rcbinfo(MppDev dev,Vdpu382RcbInfo * rcb_info)163 RK_S32 vdpu382_set_rcbinfo(MppDev dev, Vdpu382RcbInfo *rcb_info)
164 {
165     MppDevRcbInfoCfg rcb_cfg;
166     RK_U32 i;
167     /*
168      * RCB_SET_BY_SIZE_SORT_MODE: by size sort
169      * RCB_SET_BY_PRIORITY_MODE: by priority
170      */
171     Vdpu382RcbSetMode_e set_rcb_mode = RCB_SET_BY_PRIORITY_MODE;
172     RK_U32 rcb_priority[RCB_BUF_COUNT] = {
173         RCB_DBLK_ROW,
174         RCB_INTRA_ROW,
175         RCB_SAO_ROW,
176         RCB_INTER_ROW,
177         RCB_FBC_ROW,
178         RCB_TRANSD_ROW,
179         RCB_STRMD_ROW,
180         RCB_INTER_COL,
181         RCB_FILT_COL,
182         RCB_TRANSD_COL,
183     };
184 
185     switch (set_rcb_mode) {
186     case RCB_SET_BY_SIZE_SORT_MODE : {
187         Vdpu382RcbInfo info[RCB_BUF_COUNT];
188 
189         memcpy(info, rcb_info, sizeof(info));
190         qsort(info, MPP_ARRAY_ELEMS(info),
191               sizeof(info[0]), vdpu382_compare_rcb_size);
192 
193         for (i = 0; i < MPP_ARRAY_ELEMS(info); i++) {
194             rcb_cfg.reg_idx = info[i].reg;
195             rcb_cfg.size = info[i].size;
196             if (rcb_cfg.size > 0) {
197                 mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg);
198             } else
199                 break;
200         }
201     } break;
202     case RCB_SET_BY_PRIORITY_MODE : {
203         Vdpu382RcbInfo *info = rcb_info;
204         RK_U32 index = 0;
205 
206         for (i = 0; i < MPP_ARRAY_ELEMS(rcb_priority); i ++) {
207             index = rcb_priority[i];
208 
209             rcb_cfg.reg_idx = info[index].reg;
210             rcb_cfg.size = info[index].size;
211             if (rcb_cfg.size > 0) {
212                 mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg);
213             }
214         }
215     } break;
216     default:
217         break;
218     }
219 
220     return 0;
221 }
222 
vdpu382_setup_statistic(Vdpu382RegCommon * com,Vdpu382RegStatistic * sta)223 void vdpu382_setup_statistic(Vdpu382RegCommon *com, Vdpu382RegStatistic *sta)
224 {
225     com->reg011.pix_range_detection_e = 1;
226 
227     memset(sta, 0, sizeof(*sta));
228 
229     sta->reg256.axi_perf_work_e = 1;
230     sta->reg256.axi_perf_clr_e = 1;
231     sta->reg256.axi_cnt_type = 1;
232 
233     sta->reg257.addr_align_type = 1;
234 
235     /* set hurry */
236     sta->reg270.axi_rd_hurry_level = 3;
237     sta->reg270.axi_wr_hurry_level = 1;
238     sta->reg270.axi_wr_qos = 1;
239     sta->reg270.axi_rd_qos = 3;
240     sta->reg270.bus2mc_buffer_qos_level = 255;
241     sta->reg271_wr_wait_cycle_qos = 0;
242 }
243 
vdpu382_afbc_align_calc(MppBufSlots slots,MppFrame frame,RK_U32 expand)244 void vdpu382_afbc_align_calc(MppBufSlots slots, MppFrame frame, RK_U32 expand)
245 {
246     RK_U32 ver_stride = 0;
247     RK_U32 img_height = mpp_frame_get_height(frame);
248 
249     mpp_slots_set_prop(slots, SLOTS_HOR_ALIGN, mpp_align_64);
250     mpp_slots_set_prop(slots, SLOTS_VER_ALIGN, mpp_align_16);
251     ver_stride = mpp_align_16(img_height);
252     if (*compat_ext_fbc_buf_size) {
253         ver_stride += expand;
254     }
255     mpp_frame_set_ver_stride(frame, ver_stride);
256 }
257 
vdpu382_setup_down_scale(MppFrame frame,MppDev dev,Vdpu382RegCommon * com)258 void vdpu382_setup_down_scale(MppFrame frame, MppDev dev, Vdpu382RegCommon *com)
259 {
260     RK_U32 ver_stride = mpp_frame_get_ver_stride(frame);
261     RK_U32 hor_stride = mpp_frame_get_hor_stride(frame);
262     RK_U32 down_scale_ver =  MPP_ALIGN(ver_stride >> 1, 16);
263     RK_U32 down_scale_hor =  MPP_ALIGN(hor_stride >> 1, 16);
264     MppFrameFormat fmt = mpp_frame_get_fmt(frame);
265     MppMeta meta = mpp_frame_get_meta(frame);
266     RK_U32 down_scale_y_offset = 0;
267     RK_U32 down_scale_uv_offset = 0;
268 
269     if (MPP_FRAME_FMT_IS_FBC(fmt))
270         down_scale_y_offset = mpp_frame_get_fbc_size(frame);
271     else
272         down_scale_y_offset = ver_stride * hor_stride * 3 / 2;
273 
274     com->reg012.scale_down_en = 1;
275     com->reg029.scale_down_y_wratio = 2;
276     com->reg029.scale_down_y_hratio = 2;
277     com->reg029.scale_down_c_wratio = 2;
278     com->reg029.scale_down_c_hratio = 2;
279     com->reg030.y_scale_down_hor_stride =  MPP_ALIGN(down_scale_hor, 16) >> 4;
280     com->reg031.uv_scale_down_hor_stride = MPP_ALIGN(down_scale_hor, 16) >> 4;
281 
282     down_scale_y_offset = MPP_ALIGN(down_scale_y_offset, 16);
283     mpp_dev_set_reg_offset(dev, 198, down_scale_y_offset);
284     mpp_meta_set_s32(meta, KEY_DEC_TBN_Y_OFFSET, down_scale_y_offset);
285 
286     down_scale_uv_offset = down_scale_y_offset + down_scale_hor * down_scale_ver;
287     mpp_dev_set_reg_offset(dev, 199, down_scale_uv_offset);
288     mpp_meta_set_s32(meta, KEY_DEC_TBN_UV_OFFSET, down_scale_uv_offset);
289 }
290