xref: /rockchip-linux_mpp/mpp/base/mpp_sys_cfg.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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