1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "mpp_sys_cfg"
7
8 #include <string.h>
9
10 #include "rk_mpp_cfg.h"
11
12 #include "mpp_env.h"
13 #include "mpp_mem.h"
14 #include "mpp_list.h"
15 #include "mpp_time.h"
16 #include "mpp_debug.h"
17 #include "mpp_common.h"
18 #include "mpp_thread.h"
19 #include "mpp_singleton.h"
20
21 #include "mpp_cfg.h"
22 #include "mpp_soc.h"
23 #include "mpp_trie.h"
24 #include "mpp_sys_cfg.h"
25 #include "mpp_mem_pool.h"
26 #include "mpp_compat_impl.h"
27
28 #define SYS_CFG_DBG_FUNC (0x00000001)
29 #define SYS_CFG_DBG_INFO (0x00000002)
30 #define SYS_CFG_DBG_SET (0x00000004)
31 #define SYS_CFG_DBG_GET (0x00000008)
32 #define SYS_CFG_DBG_DEC_BUF (0x00000010)
33
34 #define sys_cfg_dbg(flag, fmt, ...) _mpp_dbg_f(mpp_sys_cfg_debug, flag, fmt, ## __VA_ARGS__)
35
36 #define sys_cfg_dbg_func(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_FUNC, fmt, ## __VA_ARGS__)
37 #define sys_cfg_dbg_info(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_INFO, fmt, ## __VA_ARGS__)
38 #define sys_cfg_dbg_set(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_SET, fmt, ## __VA_ARGS__)
39 #define sys_cfg_dbg_get(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_GET, fmt, ## __VA_ARGS__)
40 #define sys_cfg_dbg_dec_buf(fmt, ...) sys_cfg_dbg(SYS_CFG_DBG_DEC_BUF, fmt, ## __VA_ARGS__)
41
42 #define get_srv_sys_cfg_f() \
43 ({ \
44 MppSysCfgSrv *__tmp; \
45 if (srv_sys_cfg) { \
46 __tmp = srv_sys_cfg; \
47 } else { \
48 mpp_sys_cfg_srv_init(); \
49 __tmp = srv_sys_cfg; \
50 if (!__tmp) \
51 mpp_err("mpp sys cfg srv not init at %s\n", __FUNCTION__); \
52 } \
53 __tmp; \
54 })
55
56 typedef struct MppSysCfgSrv_t {
57 MppTrie trie;
58 MppMemPool pool;
59 } MppSysCfgSrv;
60
61 static MppSysCfgSrv *srv_sys_cfg = NULL;
62 static RK_U32 mpp_sys_cfg_debug = 0;
63
64 #define EXPAND_AS_TRIE(base, name, cfg_type, in_type, flag, field_change, field_data) \
65 do { \
66 MppCfgInfo tmp = { \
67 CFG_FUNC_TYPE_##cfg_type, \
68 (RK_U32)((long)&(((MppSysCfgSet *)0)->field_change.change)), \
69 (RK_U32)((long)&(((MppSysCfgSet *)0)->field_change.field_data)), \
70 sizeof((((MppSysCfgSet *)0)->field_change.field_data)), \
71 }; \
72 mpp_trie_add_info(srv->trie, #base":"#name, &tmp, sizeof(tmp)); \
73 } while (0);
74
75 #define ENTRY_TABLE(ENTRY) \
76 ENTRY(dec_buf_chk, enable, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_ENABLE, dec_buf_chk, enable) \
77 ENTRY(dec_buf_chk, type, u32, MppCodingType, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_TYPE, dec_buf_chk, type) \
78 ENTRY(dec_buf_chk, fmt_codec, u32, MppFrameFormat, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FMT_CODEC, dec_buf_chk, fmt_codec) \
79 ENTRY(dec_buf_chk, fmt_fbc, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FMT_FBC, dec_buf_chk, fmt_fbc) \
80 ENTRY(dec_buf_chk, fmt_hdr, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FMT_HDR, dec_buf_chk, fmt_hdr) \
81 ENTRY(dec_buf_chk, width, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_WIDTH, dec_buf_chk, width) \
82 ENTRY(dec_buf_chk, height, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_HEIGHT, dec_buf_chk, height) \
83 ENTRY(dec_buf_chk, crop_top, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_TOP, dec_buf_chk, crop_top) \
84 ENTRY(dec_buf_chk, crop_bottom, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_BOTTOM, dec_buf_chk, crop_bottom) \
85 ENTRY(dec_buf_chk, crop_left, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_LEFT, dec_buf_chk, crop_left) \
86 ENTRY(dec_buf_chk, crop_right, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_RIGHT, dec_buf_chk, crop_right) \
87 ENTRY(dec_buf_chk, unit_size, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_CROP_RIGHT, dec_buf_chk, unit_size) \
88 ENTRY(dec_buf_chk, has_metadata, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FLAG_METADATA, dec_buf_chk, has_metadata) \
89 ENTRY(dec_buf_chk, has_thumbnail, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_FLAG_THUMBNAIL, dec_buf_chk, has_thumbnail) \
90 ENTRY(dec_buf_chk, h_stride_by_byte, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_H_STRIDE_BYTE, dec_buf_chk, h_stride_by_byte) \
91 ENTRY(dec_buf_chk, v_stride, u32, RK_U32, MPP_SYS_DEC_BUF_CHK_CFG_CHANGE_V_STRIDE, dec_buf_chk, v_stride) \
92 /* read-only config */ \
93 ENTRY(dec_buf_chk, cap_fbc, u32, RK_U32, 0, dec_buf_chk, cap_fbc) \
94 ENTRY(dec_buf_chk, cap_tile, u32, RK_U32, 0, dec_buf_chk, cap_tile) \
95 ENTRY(dec_buf_chk, h_stride_by_pixel, u32, RK_U32, 0, dec_buf_chk, h_stride_by_pixel) \
96 ENTRY(dec_buf_chk, offset_y, u32, RK_U32, 0, dec_buf_chk, offset_y) \
97 ENTRY(dec_buf_chk, size_total, u32, RK_U32, 0, dec_buf_chk, size_total) \
98 ENTRY(dec_buf_chk, size_fbc_hdr, u32, RK_U32, 0, dec_buf_chk, size_fbc_hdr) \
99 ENTRY(dec_buf_chk, size_fbc_bdy, u32, RK_U32, 0, dec_buf_chk, size_fbc_bdy) \
100 ENTRY(dec_buf_chk, size_metadata, u32, RK_U32, 0, dec_buf_chk, size_metadata) \
101 ENTRY(dec_buf_chk, size_thumbnail, u32, RK_U32, 0, dec_buf_chk, size_thumbnail)
102
mpp_sys_cfg_srv_init()103 static void mpp_sys_cfg_srv_init()
104 {
105 MppSysCfgSrv *srv = srv_sys_cfg;
106
107 mpp_env_get_u32("mpp_sys_cfg_debug", &mpp_sys_cfg_debug, mpp_sys_cfg_debug);
108
109 if (srv)
110 return ;
111
112 srv = mpp_calloc(MppSysCfgSrv, 1);
113 if (!srv) {
114 mpp_err_f("failed to allocate sys cfg set service\n");
115 return ;
116 }
117
118 mpp_trie_init(&srv->trie, "MppSysCfg");
119 srv->pool = mpp_mem_pool_init_f(MODULE_TAG, sizeof(MppSysCfgSet));
120 if (!srv->trie || !srv->pool) {
121 mpp_err_f("failed to init sys cfg set service\n");
122 if (srv->trie) {
123 mpp_trie_deinit(srv->trie);
124 srv->trie = NULL;
125 }
126 if (srv->pool) {
127 mpp_mem_pool_deinit_f(srv->pool);
128 srv->pool = NULL;
129 }
130 MPP_FREE(srv);
131 return ;
132 }
133
134 srv_sys_cfg = srv;
135
136 ENTRY_TABLE(EXPAND_AS_TRIE)
137 mpp_trie_add_info(srv->trie, NULL, NULL, 0);
138
139 sys_cfg_dbg_func("info cnt %d node cnt %d size %d\n",
140 mpp_trie_get_info_count(srv->trie),
141 mpp_trie_get_node_count(srv->trie),
142 mpp_trie_get_buf_size(srv->trie));
143 }
144
mpp_sys_cfg_srv_deinit()145 static void mpp_sys_cfg_srv_deinit()
146 {
147 MppSysCfgSrv *srv = srv_sys_cfg;
148
149 if (!srv)
150 return ;
151
152 if (srv->trie) {
153 mpp_trie_deinit(srv->trie);
154 srv->trie = NULL;
155 }
156 if (srv->pool) {
157 mpp_mem_pool_deinit_f(srv->pool);
158 srv->pool = NULL;
159 }
160
161 MPP_FREE(srv_sys_cfg);
162 }
163
MPP_SINGLETON(MPP_SGLN_SYS_CFG,mpp_sys_cfg,mpp_sys_cfg_srv_init,mpp_sys_cfg_srv_deinit)164 MPP_SINGLETON(MPP_SGLN_SYS_CFG, mpp_sys_cfg, mpp_sys_cfg_srv_init, mpp_sys_cfg_srv_deinit)
165
166 static MppSysCfgSet *srv_get_cfg(MppSysCfgSrv *srv)
167 {
168 MppSysCfgSet *node = (MppSysCfgSet*)mpp_mem_pool_get_f(srv->pool);
169
170 node->dec_buf_chk.type = MPP_VIDEO_CodingUnused;
171
172 return node;
173 }
174
srv_put_cfg(MppSysCfgSrv * srv,MppSysCfgSet * node)175 static MPP_RET srv_put_cfg(MppSysCfgSrv *srv, MppSysCfgSet *node)
176 {
177 mpp_mem_pool_put_f(srv->pool, node);
178
179 return MPP_OK;
180 }
181
mpp_sys_cfg_get(MppSysCfg * cfg)182 MPP_RET mpp_sys_cfg_get(MppSysCfg *cfg)
183 {
184 MppSysCfgSrv *srv = get_srv_sys_cfg_f();
185
186 if (!cfg) {
187 mpp_err_f("invalid NULL input config\n");
188 return MPP_ERR_NULL_PTR;
189 }
190
191 *cfg = NULL;
192
193 if (!srv)
194 return MPP_NOK;
195
196 mpp_env_get_u32("mpp_sys_cfg_debug", &mpp_sys_cfg_debug, mpp_sys_cfg_debug);
197
198 *cfg = srv_get_cfg(srv);
199
200 return *cfg ? MPP_OK : MPP_NOK;
201 }
202
mpp_sys_cfg_put(MppSysCfg cfg)203 MPP_RET mpp_sys_cfg_put(MppSysCfg cfg)
204 {
205 MppSysCfgSrv *srv = get_srv_sys_cfg_f();
206
207 if (!srv)
208 return MPP_NOK;
209
210 return srv_put_cfg(srv, (MppSysCfgSet *)cfg);
211 }
212
213 typedef enum SysCfgAlignType_e {
214 SYS_CFG_ALIGN_8,
215 SYS_CFG_ALIGN_16,
216 SYS_CFG_ALIGN_32,
217 SYS_CFG_ALIGN_64,
218 SYS_CFG_ALIGN_128,
219 SYS_CFG_ALIGN_256,
220 SYS_CFG_ALIGN_256_ODD,
221 SYS_CFG_ALIGN_128_ODD_PLUS_64,
222 SYS_CFG_ALIGN_LEN_DEFAULT,
223 SYS_CFG_ALIGN_LEN_420,
224 SYS_CFG_ALIGN_LEN_422,
225 SYS_CFG_ALIGN_LEN_444,
226 SYS_CFG_ALIGN_LEN_422_AVC,
227 SYS_CFG_ALIGN_LEN_420_AV1,
228 SYS_CFG_ALIGN_LEN_422_AV1,
229 SYS_CFG_ALIGN_BUTT,
230 } SysCfgAlignType;
231
mpp_sys_cfg_align(SysCfgAlignType type,RK_U32 val)232 static RK_U32 mpp_sys_cfg_align(SysCfgAlignType type, RK_U32 val)
233 {
234 switch (type) {
235 case SYS_CFG_ALIGN_8: { return MPP_ALIGN(val, 8);};
236 case SYS_CFG_ALIGN_16: { return MPP_ALIGN(val, 16);};
237 case SYS_CFG_ALIGN_32: { return MPP_ALIGN(val, 32);};
238 case SYS_CFG_ALIGN_64: { return MPP_ALIGN(val, 64);};
239 case SYS_CFG_ALIGN_128: { return MPP_ALIGN(val, 128);};
240 case SYS_CFG_ALIGN_256: { return MPP_ALIGN(val, 256);};
241 case SYS_CFG_ALIGN_256_ODD: {return MPP_ALIGN(val, 256) | 256;};
242 case SYS_CFG_ALIGN_128_ODD_PLUS_64: {
243 val = MPP_ALIGN(val, 64);
244 if (((val - 64) % 256 == 128))
245 return val;
246 else
247 return ((MPP_ALIGN(val, 128) | 128) + 64);
248 };
249 case SYS_CFG_ALIGN_LEN_DEFAULT: { return (9 * MPP_ALIGN(val, 16) / 5);};
250 case SYS_CFG_ALIGN_LEN_420:
251 case SYS_CFG_ALIGN_LEN_422: { return (2 * MPP_ALIGN(val, 16));};
252 case SYS_CFG_ALIGN_LEN_444: { return (3 * MPP_ALIGN(val, 16));};
253 case SYS_CFG_ALIGN_LEN_422_AVC: { return ((5 * MPP_ALIGN(val, 16)) / 2);};
254 case SYS_CFG_ALIGN_LEN_420_AV1: { return (2 * MPP_ALIGN(val, 128));};
255 case SYS_CFG_ALIGN_LEN_422_AV1: { return ((5 * MPP_ALIGN(val, 64)) / 2);};
256 default: {
257 mpp_err("Specifying the align type is necessary");
258 return MPP_NOK;
259 };
260 }
261 }
262
263 /* Based on drm_gem_framebuffer_helper.c drm_gem_afbc_min_size() */
get_afbc_min_size(RK_S32 width,RK_S32 height,RK_S32 bpp)264 static RK_S32 get_afbc_min_size(RK_S32 width, RK_S32 height, RK_S32 bpp)
265 {
266 #define AFBC_HEADER_SIZE 16
267 #define AFBC_HDR_ALIGN 64
268 #define AFBC_SUPERBLOCK_PIXELS 256
269 #define AFBC_SUPERBLOCK_ALIGNMENT 128
270
271 RK_S32 n_blocks, hdr_alignment, size;
272
273 /* AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 and !AFBC_FORMAT_MOD_TILED */
274 width = MPP_ALIGN(width, 16);
275 height = MPP_ALIGN(height, 16);
276 hdr_alignment = AFBC_HDR_ALIGN;
277
278 n_blocks = (width * height) / AFBC_SUPERBLOCK_PIXELS;
279
280 size = MPP_ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment);
281 size += n_blocks * MPP_ALIGN(bpp * AFBC_SUPERBLOCK_PIXELS / 8,
282 AFBC_SUPERBLOCK_ALIGNMENT);
283 return size;
284 }
285
286 /*
287 * in: fmt_fbc,type,width,h_stride
288 * out: stride_w
289 *
290 * in: fmt_fbc,type,height,v_stride
291 * out: stride_h
292 *
293 * in: fmt_fbc,type,fmt_codec,width,h_stride
294 * out: h_stride_by_byte
295 *
296 * in: fmt_fbc,type,fmt_codec,width,height,h_stride,v_stride
297 * out: buffer_size
298 */
mpp_sys_dec_buf_chk_proc(MppSysDecBufChkCfg * cfg)299 MPP_RET mpp_sys_dec_buf_chk_proc(MppSysDecBufChkCfg *cfg)
300 {
301 MppCodingType type = cfg->type;
302 MppFrameFormat fmt = (MppFrameFormat)(((RK_U32)cfg->fmt_codec & MPP_FRAME_FMT_MASK) |
303 (cfg->fmt_fbc & MPP_FRAME_FBC_MASK) |
304 (cfg->fmt_hdr & MPP_FRAME_HDR_MASK));
305 MppFrameFormat fmt_raw = cfg->fmt_codec;
306
307 RK_U32 aligned_pixel = 0;
308 RK_U32 aligned_pixel_byte = 0;
309 RK_U32 aligned_byte = 0;
310 RK_U32 aligned_height = 0;
311 RK_U32 size_total = 0;
312 RK_U32 size_total_old = 0;
313 RK_U32 depth = MPP_FRAME_FMT_IS_YUV_10BIT(fmt) ? 10 : 8;
314
315 if (type == MPP_VIDEO_CodingUnused) {
316 mpp_err("The coding type is invalid");
317 return MPP_NOK;
318 }
319
320 /* use codec stride */
321 if (cfg->h_stride_by_byte)
322 aligned_pixel = cfg->h_stride_by_byte * 8 / depth;
323 if (cfg->v_stride)
324 aligned_height = cfg->v_stride;
325
326 sys_cfg_dbg_dec_buf("org pixel wxh: [%d %d]\n", cfg->width, cfg->height);
327 sys_cfg_dbg_dec_buf("outside stride wxh: [%d %d]\n",
328 cfg->h_stride_by_byte, cfg->v_stride);
329 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
330 /* fbc case */
331 switch (type) {
332 case MPP_VIDEO_CodingHEVC :
333 case MPP_VIDEO_CodingAV1 : {
334 aligned_pixel = MPP_ALIGN(cfg->width, 64);
335 aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16);
336 } break;
337 case MPP_VIDEO_CodingAVC :
338 case MPP_VIDEO_CodingAVSPLUS :
339 case MPP_VIDEO_CodingAVS :
340 case MPP_VIDEO_CodingAVS2 : {
341 aligned_pixel = MPP_ALIGN(cfg->width, 64);
342 aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16);
343 } break;
344 case MPP_VIDEO_CodingVP9 : {
345 aligned_pixel = MPP_ALIGN(cfg->width, 64);
346 aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 64);
347 } break;
348 default : {
349 aligned_pixel = MPP_ALIGN(cfg->width, 16);
350 aligned_height = MPP_ALIGN(aligned_height ? aligned_height : cfg->height, 16);
351 } break;
352 }
353 sys_cfg_dbg_dec_buf("spec aligned pixel wxh: [%d %d]\n", aligned_pixel, aligned_height);
354
355 /*fbc stride default 64 align*/
356 if (*compat_ext_fbc_hdr_256_odd)
357 aligned_pixel_byte = (MPP_ALIGN(aligned_pixel, 256) | 256) * depth >> 3;
358 else
359 aligned_pixel_byte = MPP_ALIGN(aligned_pixel, 64) * depth >> 3;
360 sys_cfg_dbg_dec_buf("need 256 odd align: %d\n", *compat_ext_fbc_hdr_256_odd);
361
362 switch (type) {
363 case MPP_VIDEO_CodingAVC :
364 case MPP_VIDEO_CodingAVSPLUS :
365 case MPP_VIDEO_CodingAVS :
366 case MPP_VIDEO_CodingAVS2 : {
367 aligned_byte = MPP_ALIGN(aligned_pixel_byte, 64);
368 } break;
369 case MPP_VIDEO_CodingHEVC : {
370 aligned_byte = MPP_ALIGN(aligned_pixel_byte, 64);
371 } break;
372 case MPP_VIDEO_CodingVP9 : {
373 aligned_byte = MPP_ALIGN(aligned_pixel_byte, 64);
374 } break;
375 case MPP_VIDEO_CodingAV1 : {
376 aligned_byte = MPP_ALIGN(aligned_pixel_byte, 16);
377 } break;
378 default : {
379 aligned_byte = MPP_ALIGN(aligned_pixel_byte, 16);
380 } break;
381 }
382 sys_cfg_dbg_dec_buf("dec hw aligned hor_byte: [%d]\n", aligned_byte);
383
384 cfg->h_stride_by_byte = aligned_byte;
385 cfg->h_stride_by_pixel = aligned_pixel;
386 cfg->v_stride = aligned_height;
387
388 switch ((fmt_raw & MPP_FRAME_FMT_MASK)) {
389 case MPP_FMT_YUV420SP_10BIT : {
390 size_total = get_afbc_min_size(aligned_pixel, aligned_height, 15);
391 } break;
392 case MPP_FMT_YUV422SP_10BIT : {
393 size_total = get_afbc_min_size(aligned_pixel, aligned_height, 20);
394 } break;
395 case MPP_FMT_YUV420SP : {
396 size_total = get_afbc_min_size(aligned_pixel, aligned_height, 12);
397 } break;
398 case MPP_FMT_YUV422SP : {
399 size_total = get_afbc_min_size(aligned_pixel, aligned_height, 16);
400 } break;
401 case MPP_FMT_YUV444SP : {
402 size_total = get_afbc_min_size(aligned_pixel, aligned_height, 24);
403 } break;
404 case MPP_FMT_YUV444SP_10BIT : {
405 size_total = get_afbc_min_size(aligned_pixel, aligned_height, 30);
406 } break;
407 default : {
408 size_total = aligned_byte * aligned_height * 3 / 2;
409 mpp_err("dec out fmt 0x%x is no support", fmt_raw & MPP_FRAME_FMT_MASK);
410 } break;
411 }
412 sys_cfg_dbg_dec_buf("res aligned_pixel %d\n", aligned_pixel);
413 sys_cfg_dbg_dec_buf("res aligned_byte %d\n", aligned_byte);
414 sys_cfg_dbg_dec_buf("res aligned_height %d\n", aligned_height);
415 sys_cfg_dbg_dec_buf("res GPU aligned size_total: [%d]\n", size_total);
416
417 cfg->size_total = size_total;
418 } else {
419 /* tile case */
420 /* raster case */
421 RockchipSocType soc_type = mpp_get_soc_type();
422
423 aligned_pixel = cfg->width;
424 switch (type) {
425 case MPP_VIDEO_CodingHEVC : {
426 aligned_pixel = MPP_ALIGN(cfg->width, 64);
427 aligned_height = MPP_ALIGN(cfg->height, 8);
428 } break;
429 /*
430 * avc aligned to ctu
431 * p_Vid->width = p_Vid->PicWidthInMbs * 16
432 * p_Vid->height = p_Vid->FrameHeightInMbs * 16
433 */
434 case MPP_VIDEO_CodingAVC : {
435 aligned_pixel = MPP_ALIGN(cfg->width, 16);
436 aligned_height = MPP_ALIGN(cfg->height, 16);
437 } break;
438 case MPP_VIDEO_CodingVP9 : {
439 if (soc_type == ROCKCHIP_SOC_RK3399)
440 aligned_height = MPP_ALIGN(cfg->height, 64);
441 else if (soc_type == ROCKCHIP_SOC_RK3588)
442 aligned_height = MPP_ALIGN(cfg->height, 16);
443 else
444 aligned_height = MPP_ALIGN(cfg->height, 8);
445 } break;
446 case MPP_VIDEO_CodingAV1 : {
447 aligned_height = MPP_ALIGN(cfg->height, 8);
448 } break;
449 case MPP_VIDEO_CodingVP8 :
450 case MPP_VIDEO_CodingH263 :
451 case MPP_VIDEO_CodingMPEG2 :
452 case MPP_VIDEO_CodingMPEG4 : {
453 aligned_height = MPP_ALIGN(cfg->height, 16);
454 } break;
455 case MPP_VIDEO_CodingAVS2 : {
456 aligned_pixel = MPP_ALIGN(cfg->width, 64);
457 aligned_height = MPP_ALIGN(cfg->height, 8);
458 } break;
459 default : {
460 aligned_height = MPP_ALIGN(cfg->height, 8);
461 } break;
462 }
463 sys_cfg_dbg_dec_buf("spec aligned pixel wxh: [%d %d]\n", aligned_pixel, aligned_height);
464
465 aligned_pixel_byte = cfg->h_stride_by_byte ? cfg->h_stride_by_byte :
466 aligned_pixel * depth / 8;
467 aligned_height = cfg->v_stride ? cfg->v_stride : aligned_height;
468
469 switch (type) {
470 case MPP_VIDEO_CodingHEVC : {
471 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_64, aligned_pixel_byte);
472 } break;
473 case MPP_VIDEO_CodingVP9 : {
474 if (soc_type == ROCKCHIP_SOC_RK3576)
475 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_128_ODD_PLUS_64,
476 aligned_pixel_byte);
477 else
478 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_256_ODD, aligned_pixel_byte);
479 } break;
480 case MPP_VIDEO_CodingAV1 : {
481 if (soc_type == ROCKCHIP_SOC_RK3588)
482 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_16, aligned_pixel_byte);
483 else
484 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_128, aligned_pixel_byte);
485 } break;
486 default : {
487 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_16, aligned_pixel_byte);
488 } break;
489 }
490 sys_cfg_dbg_dec_buf("dec hw aligned hor_byte: [%d %d]\n", aligned_byte);
491
492 /*
493 * NOTE: rk3576 use 128 odd plus 64 for all non jpeg format
494 * all the other socs use 256 odd on larger than 1080p
495 */
496 if ((aligned_byte > 1920 || soc_type == ROCKCHIP_SOC_RK3576)
497 && type != MPP_VIDEO_CodingMJPEG) {
498 rk_s32 update = 0;
499
500 switch (soc_type) {
501 case ROCKCHIP_SOC_RK3399 :
502 case ROCKCHIP_SOC_RK3568 :
503 case ROCKCHIP_SOC_RK3562 :
504 case ROCKCHIP_SOC_RK3528 :
505 case ROCKCHIP_SOC_RK3588 : {
506 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_256_ODD, aligned_byte);
507 update = 1;
508 } break;
509 case ROCKCHIP_SOC_RK3576 : {
510 aligned_byte = mpp_sys_cfg_align(SYS_CFG_ALIGN_128_ODD_PLUS_64, aligned_byte);
511 update = 1;
512 } break;
513 default : {
514 } break;
515 }
516
517 /*
518 * recalc aligned_pixel here
519 * NOTE: no RGB format here in fact
520 */
521 if (update) {
522 switch (fmt & MPP_FRAME_FMT_MASK) {
523 case MPP_FMT_YUV420SP_10BIT:
524 case MPP_FMT_YUV422SP_10BIT:
525 case MPP_FMT_YUV444SP_10BIT: {
526 aligned_pixel = aligned_byte * 8 / 10;
527 } break;
528 case MPP_FMT_YUV422_YVYU:
529 case MPP_FMT_YUV422_YUYV:
530 case MPP_FMT_RGB565:
531 case MPP_FMT_BGR565: {
532 aligned_pixel = aligned_byte / 2;
533 } break;
534 case MPP_FMT_RGB888:
535 case MPP_FMT_BGR888: {
536 aligned_pixel = aligned_byte / 3;
537 } break;
538 default : {
539 aligned_pixel = aligned_byte;
540 } break;
541 }
542 }
543 }
544 sys_cfg_dbg_dec_buf("dec hw performance aligned hor_byte: [%d]\n", aligned_pixel);
545
546 cfg->h_stride_by_byte = aligned_byte;
547 cfg->h_stride_by_pixel = aligned_pixel;
548 cfg->v_stride = aligned_height;
549
550 size_total = aligned_byte * aligned_height;
551 size_total_old = size_total;
552 sys_cfg_dbg_dec_buf("fmt_raw %x\n", fmt_raw);
553 sys_cfg_dbg_dec_buf("res aligned_pixel %d\n", aligned_pixel);
554 sys_cfg_dbg_dec_buf("res aligned_byte %d\n", aligned_byte);
555 sys_cfg_dbg_dec_buf("res aligned_height %d\n", aligned_height);
556
557 switch (fmt_raw) {
558 case MPP_FMT_YUV420SP :
559 case MPP_FMT_YUV420SP_10BIT :
560 case MPP_FMT_YUV420P :
561 case MPP_FMT_YUV420SP_VU : {
562 SysCfgAlignType align_type = SYS_CFG_ALIGN_LEN_DEFAULT;
563
564 /* hevc and vp9 - SYS_CFG_ALIGN_LEN_DEFAULT */
565 if (type == MPP_VIDEO_CodingAV1)
566 align_type = SYS_CFG_ALIGN_LEN_420_AV1;
567 else if (type == MPP_VIDEO_CodingAVC)
568 align_type = SYS_CFG_ALIGN_LEN_420;
569
570 size_total = mpp_sys_cfg_align(align_type, size_total);
571 } break;
572 case MPP_FMT_YUV422SP :
573 case MPP_FMT_YUV422SP_10BIT :
574 case MPP_FMT_YUV422P :
575 case MPP_FMT_YUV422SP_VU :
576 case MPP_FMT_YUV422_YUYV :
577 case MPP_FMT_YUV422_YVYU :
578 case MPP_FMT_YUV422_UYVY :
579 case MPP_FMT_YUV422_VYUY :
580 case MPP_FMT_YUV440SP :
581 case MPP_FMT_YUV411SP : {
582 SysCfgAlignType align_type;
583
584 if (type == MPP_VIDEO_CodingAVC)
585 align_type = SYS_CFG_ALIGN_LEN_422_AVC;
586 else if (type == MPP_VIDEO_CodingAV1)
587 align_type = SYS_CFG_ALIGN_LEN_422_AV1;
588 else
589 align_type = SYS_CFG_ALIGN_LEN_422;
590
591 size_total = mpp_sys_cfg_align(align_type, size_total);
592 } break;
593 case MPP_FMT_YUV400 : {
594 /* do nothing */
595 } break;
596 case MPP_FMT_YUV444SP :
597 case MPP_FMT_YUV444P :
598 case MPP_FMT_YUV444SP_10BIT : {
599 size_total = mpp_sys_cfg_align(SYS_CFG_ALIGN_LEN_444, size_total);
600 } break;
601 default : {
602 size_total = size_total * 3 / 2;
603 }
604 }
605 sys_cfg_dbg_dec_buf("res size total %d -> %d\n", size_total_old, size_total);
606
607 cfg->size_total = size_total;
608 }
609
610 return MPP_OK;
611 }
612
mpp_sys_cfg_ioctl(MppSysCfg cfg)613 MPP_RET mpp_sys_cfg_ioctl(MppSysCfg cfg)
614 {
615 MppSysCfgSet *p = (MppSysCfgSet *)cfg;
616
617 if (!cfg) {
618 mpp_err_f("invalid NULL input config\n");
619 return MPP_ERR_NULL_PTR;
620 }
621
622 if (p->dec_buf_chk.enable) {
623 mpp_sys_dec_buf_chk_proc(&p->dec_buf_chk);
624 p->dec_buf_chk.enable = 0;
625 }
626
627 return MPP_OK;
628 }
629
630 #define MPP_CFG_SET_ACCESS(func_name, in_type, cfg_type) \
631 MPP_RET func_name(MppSysCfg cfg, const char *name, in_type val) \
632 { \
633 MppSysCfgSrv *srv = get_srv_sys_cfg_f(); \
634 MppSysCfgSet *p; \
635 MppTrieInfo *node; \
636 MppCfgInfo *info; \
637 if (!srv) \
638 return MPP_NOK; \
639 if (!cfg || !name) { \
640 mpp_err_f("invalid input cfg %p name %p\n", cfg, name); \
641 return MPP_ERR_NULL_PTR; \
642 } \
643 p = (MppSysCfgSet *)cfg; \
644 node = mpp_trie_get_info(srv->trie, name); \
645 info = (MppCfgInfo *)mpp_trie_info_ctx(node); \
646 if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
647 return MPP_NOK; \
648 } \
649 if (!info->flag_offset) { \
650 mpp_log_f("can not set readonly cfg %s\n", mpp_trie_info_name(node)); \
651 return MPP_NOK; \
652 } \
653 sys_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), \
654 strof_cfg_type(info->data_type)); \
655 MPP_RET ret = MPP_CFG_SET_##cfg_type(info, p, val); \
656 return ret; \
657 }
658
659 MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_s32, RK_S32, s32);
660 MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_u32, RK_U32, u32);
661 MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_s64, RK_S64, s64);
662 MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_u64, RK_U64, u64);
663 MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_ptr, void *, ptr);
664 MPP_CFG_SET_ACCESS(mpp_sys_cfg_set_st, void *, st);
665
666 #define MPP_CFG_GET_ACCESS(func_name, in_type, cfg_type) \
667 MPP_RET func_name(MppSysCfg cfg, const char *name, in_type *val) \
668 { \
669 MppSysCfgSrv *srv = get_srv_sys_cfg_f(); \
670 MppSysCfgSet *p; \
671 MppTrieInfo *node; \
672 MppCfgInfo *info; \
673 if (!srv) \
674 return MPP_NOK; \
675 if (!cfg || !name) { \
676 mpp_err_f("invalid input cfg %p name %p\n", cfg, name); \
677 return MPP_ERR_NULL_PTR; \
678 } \
679 p = (MppSysCfgSet *)cfg; \
680 node = mpp_trie_get_info(srv->trie, name); \
681 info = (MppCfgInfo *)mpp_trie_info_ctx(node); \
682 if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
683 return MPP_NOK; \
684 } \
685 sys_cfg_dbg_set("name %s type %s\n", mpp_trie_info_name(node), \
686 strof_cfg_type(info->data_type)); \
687 MPP_RET ret = MPP_CFG_GET_##cfg_type(info, p, val); \
688 return ret; \
689 }
690
691 MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_s32, RK_S32, s32);
692 MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_u32, RK_U32, u32);
693 MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_s64, RK_S64, s64);
694 MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_u64, RK_U64, u64);
695 MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_ptr, void *, ptr);
696 MPP_CFG_GET_ACCESS(mpp_sys_cfg_get_st, void , st);
697
mpp_sys_cfg_show(void)698 void mpp_sys_cfg_show(void)
699 {
700 MppSysCfgSrv *srv = get_srv_sys_cfg_f();
701 MppTrieInfo *root;
702 MppTrie trie;
703
704 if (!srv)
705 return ;
706
707 trie = srv->trie;
708 root = mpp_trie_get_info_first(trie);
709
710 mpp_log("dumping valid configure string start\n");
711
712 if (root) {
713 MppTrieInfo *node = root;
714 rk_s32 len = mpp_trie_get_name_max(trie);
715
716 do {
717 if (mpp_trie_info_is_self(node))
718 continue;
719
720 if (node->ctx_len == sizeof(MppCfgInfo)) {
721 MppCfgInfo *info = (MppCfgInfo *)mpp_trie_info_ctx(node);
722
723 mpp_log("%-*s type %s - %d:%d\n", len, mpp_trie_info_name(node),
724 strof_cfg_type(info->data_type), info->data_offset, info->data_size);
725 } else {
726 mpp_log("%-*s size - %d\n", len, mpp_trie_info_name(node), node->ctx_len);
727 }
728 } while ((node = mpp_trie_get_info_next(trie, node)));
729 }
730 mpp_log("dumping valid configure string done\n");
731
732 mpp_log("sys cfg size %d count %d with trie node %d size %d\n",
733 sizeof(MppSysCfgSet), mpp_trie_get_info_count(trie),
734 mpp_trie_get_node_count(trie), mpp_trie_get_buf_size(trie));
735 }
736