1 /*
2 * Copyright 2020 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 "vdpu34x_com"
18
19 #include <string.h>
20 #include <stdlib.h>
21
22 #include "mpp_log.h"
23 #include "mpp_buffer.h"
24 #include "mpp_common.h"
25 #include "mpp_compat_impl.h"
26 #include "mpp_env.h"
27
28 #include "vdpu34x_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(Vdpu34xRcbInfo * info,RK_U32 reg,RK_S32 offset,RK_S32 len,RK_S32 idx)43 static RK_S32 update_size_offset(Vdpu34xRcbInfo *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
vdpu34x_get_rcb_buf_size(Vdpu34xRcbInfo * info,RK_S32 width,RK_S32 height)56 RK_S32 vdpu34x_get_rcb_buf_size(Vdpu34xRcbInfo *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
vdpu34x_setup_rcb(Vdpu34xRegCommonAddr * reg,MppDev dev,MppBuffer buf,Vdpu34xRcbInfo * info)75 void vdpu34x_setup_rcb(Vdpu34xRegCommonAddr *reg, MppDev dev, MppBuffer buf, Vdpu34xRcbInfo *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
vdpu34x_compare_rcb_size(const void * a,const void * b)152 static RK_S32 vdpu34x_compare_rcb_size(const void *a, const void *b)
153 {
154 Vdpu34xRcbInfo *p0 = (Vdpu34xRcbInfo *)a;
155 Vdpu34xRcbInfo *p1 = (Vdpu34xRcbInfo *)b;
156
157 return (p0->size > p1->size) ? -1 : 1;
158 }
159
vdpu34x_set_rcbinfo(MppDev dev,Vdpu34xRcbInfo * rcb_info)160 RK_S32 vdpu34x_set_rcbinfo(MppDev dev, Vdpu34xRcbInfo *rcb_info)
161 {
162 MppDevRcbInfoCfg rcb_cfg;
163 RK_U32 i;
164 /*
165 * RCB_SET_BY_SIZE_SORT_MODE: by size sort
166 * RCB_SET_BY_PRIORITY_MODE: by priority
167 */
168 Vdpu34xRcbSetMode_e set_rcb_mode = RCB_SET_BY_PRIORITY_MODE;
169 RK_U32 rcb_priority[RCB_BUF_COUNT] = {
170 RCB_DBLK_ROW,
171 RCB_INTRA_ROW,
172 RCB_SAO_ROW,
173 RCB_INTER_ROW,
174 RCB_FBC_ROW,
175 RCB_TRANSD_ROW,
176 RCB_STRMD_ROW,
177 RCB_INTER_COL,
178 RCB_FILT_COL,
179 RCB_TRANSD_COL,
180 };
181
182 switch (set_rcb_mode) {
183 case RCB_SET_BY_SIZE_SORT_MODE : {
184 Vdpu34xRcbInfo info[RCB_BUF_COUNT];
185
186 memcpy(info, rcb_info, sizeof(info));
187 qsort(info, MPP_ARRAY_ELEMS(info),
188 sizeof(info[0]), vdpu34x_compare_rcb_size);
189
190 for (i = 0; i < MPP_ARRAY_ELEMS(info); i++) {
191 rcb_cfg.reg_idx = info[i].reg;
192 rcb_cfg.size = info[i].size;
193 if (rcb_cfg.size > 0) {
194 mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg);
195 } else
196 break;
197 }
198 } break;
199 case RCB_SET_BY_PRIORITY_MODE : {
200 Vdpu34xRcbInfo *info = rcb_info;
201 RK_U32 index = 0;
202
203 for (i = 0; i < MPP_ARRAY_ELEMS(rcb_priority); i ++) {
204 index = rcb_priority[i];
205 /*
206 * If the inter row rcb buffer is placed in sram,
207 * may conflict with other buffer in ddr,
208 * will result in slower access to data and degraded decoding performance.
209 * The issue will be resolved in chips after rk3588.
210 */
211 if (index == RCB_INTER_ROW)
212 continue;
213
214 rcb_cfg.reg_idx = info[index].reg;
215 rcb_cfg.size = info[index].size;
216 if (rcb_cfg.size > 0) {
217 mpp_dev_ioctl(dev, MPP_DEV_RCB_INFO, &rcb_cfg);
218 }
219 }
220 } break;
221 default:
222 break;
223 }
224
225 return 0;
226 }
227
vdpu34x_setup_statistic(Vdpu34xRegCommon * com,Vdpu34xRegStatistic * sta)228 void vdpu34x_setup_statistic(Vdpu34xRegCommon *com, Vdpu34xRegStatistic *sta)
229 {
230 com->reg011.pix_range_detection_e = 1;
231
232 memset(sta, 0, sizeof(*sta));
233
234 sta->reg256.axi_perf_work_e = 1;
235 sta->reg256.axi_perf_clr_e = 1;
236 sta->reg256.axi_cnt_type = 1;
237
238 sta->reg257.addr_align_type = 1;
239
240 /* set hurry */
241 sta->reg270.axi_rd_hurry_level = 3;
242 sta->reg270.axi_wr_hurry_level = 1;
243 sta->reg270.axi_wr_qos = 1;
244 sta->reg270.axi_rd_qos = 3;
245 sta->reg270.bus2mc_buffer_qos_level = 255;
246 sta->reg271_wr_wait_cycle_qos = 0;
247 }
248
vdpu34x_afbc_align_calc(MppBufSlots slots,MppFrame frame,RK_U32 expand)249 void vdpu34x_afbc_align_calc(MppBufSlots slots, MppFrame frame, RK_U32 expand)
250 {
251 RK_U32 ver_stride = 0;
252 RK_U32 img_height = mpp_frame_get_height(frame);
253
254 mpp_slots_set_prop(slots, SLOTS_HOR_ALIGN, mpp_align_64);
255 mpp_slots_set_prop(slots, SLOTS_VER_ALIGN, mpp_align_16);
256 ver_stride = mpp_align_16(img_height);
257 if (*compat_ext_fbc_buf_size) {
258 ver_stride += expand;
259 }
260 mpp_frame_set_ver_stride(frame, ver_stride);
261 }
262