// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2019 MediaTek Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #if defined(CONFIG_MTK_DRAMC) && 0 #include "mtk_dramc.h" #endif #include "mmdvfs_pmqos.h" #include "layering_rule.h" #include "disp_drv_log.h" #include "ddp_rsz.h" #include "primary_display.h" #include "disp_lowpower.h" #include "mtk_disp_mgr.h" #include "disp_rect.h" static struct layering_rule_ops l_rule_ops; static struct layering_rule_info_t l_rule_info; int emi_bound_table[HRT_BOUND_NUM][HRT_LEVEL_NUM] = { /* HRT_BOUND_TYPE_LP4 */ {500, 600, 700, 700}, /* HRT_BOUND_TYPE_LP4_PLUS */ {400, 500, 600, 600}, /* HRT_BOUND_TYPE_LP3 */ {350, 350, 350, 350}, /* HRT_BOUND_TYPE_LP3_PLUS */ {250, 250, 250, 250}, /* HRT_BOUND_TYPE_LP4_1CH */ {350, 350, 350, 350}, /* HRT_BOUND_TYPE_LP4_HYBRID */ {400, 400, 400, 600}, /* HRT_BOUND_TYPE_LP3_HD */ {750, 750, 750, 750}, /* HRT_BOUND_TYPE_LP4_HD */ {1100, 1350, 1550, 1550}, /* HRT_BOUND_TYPE_LP3_HD_PLUS */ {550, 550, 550, 550}, /* HRT_BOUND_TYPE_LP4_HD_PLUS */ {900, 1100, 1350, 1350}, }; int larb_bound_table[HRT_BOUND_NUM][HRT_LEVEL_NUM] = { /* HRT_BOUND_TYPE_LP4 */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP4_PLUS */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP3 */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP3_PLUS */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP4_1CH */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP4_HYBRID */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP3_HD */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP4_HD */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP3_HD_PLUS */ {1200, 1200, 1200, 1200}, /* HRT_BOUND_TYPE_LP4_HD_PLUS */ {1200, 1200, 1200, 1200}, }; int mm_freq_table[HRT_DRAMC_TYPE_NUM][HRT_OPP_LEVEL_NUM] = { #if defined(CONFIG_MACH_MT6765) /* HRT_DRAMC_TYPE_LP4_3733 */ {457, 312, 228}, /* HRT_DRAMC_TYPE_LP4_3200 */ {457, 312, 228}, /* HRT_DRAMC_TYPE_LP3 */ {457, 312, 228}, #elif defined(CONFIG_MACH_MT6761) /* HRT_DRAMC_TYPE_LP4_3733 */ {436, 312, 227}, /* HRT_DRAMC_TYPE_LP4_3200 */ {436, 312, 227}, /* HRT_DRAMC_TYPE_LP3 */ {436, 312, 227}, #endif }; /** * The layer mapping table define ovl layer dispatch rule for both * primary and secondary display.Each table has 16 elements which * represent the layer mapping rule by the number of input layers. */ #ifndef CONFIG_MTK_ROUND_CORNER_SUPPORT static int layer_mapping_table[HRT_TB_NUM][TOTAL_OVL_LAYER_NUM] = { /* HRT_TB_TYPE_GENERAL */ {0x00010001, 0x00030003, 0x00030007, 0x0003000F, 0x0003001F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F}, /* HRT_TB_TYPE_RPO_L0 */ {0x00010001, 0x00030005, 0x0003000D, 0x0003001D, 0x0003003D, 0x0003003D, 0x0003003D, 0x0003003D, 0x0003003D, 0x0003003D, 0x0003003D, 0x0003003D}, /* HRT_TB_TYPE_RPO_DIM_L0 */ {0x00010001, 0x00030003, 0x00030007, 0x0003000F, 0x0003001F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F}, /* HRT_TB_TYPE_RPO_BOTH */ {0x00010001, 0x00030003, 0x00030007, 0x0003000F, 0x0003001F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F, 0x0003003F}, }; #else static int layer_mapping_table[HRT_TB_NUM][TOTAL_OVL_LAYER_NUM] = { /* HRT_TB_TYPE_GENERAL */ {0x00010001, 0x00030003, 0x00030007, 0x0003000F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F}, /* HRT_TB_TYPE_RPO_L0 */ {0x00010001, 0x00030005, 0x0003000D, 0x0003001D, 0x0003001D, 0x0003001D, 0x0003001D, 0x0003001D, 0x0003001D, 0x0003001D}, /* HRT_TB_TYPE_RPO_DIM_L0 */ {0x00010001, 0x00030003, 0x00030007, 0x0003000F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F}, /* HRT_TB_TYPE_RPO_BOTH */ {0x00010001, 0x00030003, 0x00030007, 0x0003000F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F, 0x0003001F}, }; #endif /** * The larb mapping table represent the relation between LARB and OVL. */ static int larb_mapping_table[HRT_TB_NUM] = { 0x00010010, 0x00010010, 0x00010010, 0x00010010, }; /** * The OVL mapping table is used to get the OVL index of correcponding layer. * The bit value 1 means the position of the last layer in OVL engine. */ #ifndef CONFIG_MTK_ROUND_CORNER_SUPPORT static int ovl_mapping_table[HRT_TB_NUM] = { 0x00020022, 0x00020022, 0x00020022, 0x00020022, }; #else static int ovl_mapping_table[HRT_TB_NUM] = { 0x00020012, 0x00020012, 0x00020012, 0x00020012, }; #endif #define GET_SYS_STATE(sys_state) \ ((l_rule_info.hrt_sys_state >> sys_state) & 0x1) static bool has_rsz_layer(struct disp_layer_info *disp_info, int disp_idx) { int i = 0; struct layer_config *c = NULL; for (i = 0; i < disp_info->layer_num[disp_idx]; i++) { c = &disp_info->input_config[disp_idx][i]; if (is_gles_layer(disp_info, disp_idx, i)) continue; if ((c->src_height != c->dst_height) || (c->src_width != c->dst_width)) return true; } return false; } static bool same_ratio(struct layer_config *input, struct layer_config *tgt) { int diff_w = (tgt->dst_width * input->src_width + (input->src_width - 1)) / input->dst_width - tgt->src_width; int diff_h = (tgt->dst_height * input->src_height + (input->src_height - 1)) / input->dst_height - tgt->src_height; if (diff_w > 1 || diff_w < -1 || diff_h > 1 || diff_h < -1) return false; return true; } #define RATIO_LIMIT 2 static bool same_ratio_limitation(struct layer_config *tgt, int limitation) { int panel_w = 0, panel_h = 0; int diff_w = 0, diff_h = 0; panel_w = primary_display_get_width(); panel_h = primary_display_get_height(); diff_w = tgt->dst_width - tgt->src_width; diff_h = tgt->dst_height - tgt->src_height; if (panel_w <= 0 || panel_h <= 0) return false; if (((100 * diff_w/panel_w < limitation) && (diff_w > 0)) || ((100 * diff_h/panel_h < limitation) && (diff_h > 0))) return true; else return false; } static bool is_RPO(struct disp_layer_info *disp_info, int disp_idx, int *rsz_idx, bool *has_dim_layer) { int i = 0; struct layer_config *c = NULL; struct layer_config *basic_layer = NULL; int gpu_rsz_idx = 0; struct disp_rect src_layer_roi = {0, 0, 0, 0}; struct disp_rect src_total_roi = {0, 0, 0, 0}; struct disp_rect dst_layer_roi = {0, 0, 0, 0}; struct disp_rect dst_total_roi = {0, 0, 0, 0}; *has_dim_layer = false; *rsz_idx = -1; if (disp_info->layer_num[disp_idx] <= 0) return false; for (i = 0; i < disp_info->layer_num[disp_idx] && i < 2; i++) { c = &disp_info->input_config[disp_idx][i]; if (i == 0 && c->src_fmt == DISP_FORMAT_DIM) { *has_dim_layer = true; continue; } if (disp_info->gles_head[disp_idx] >= 0 && disp_info->gles_head[disp_idx] <= i) break; if (c->src_width == c->dst_width && c->src_height == c->dst_height) break; if (c->src_width > c->dst_width || c->src_height > c->dst_height) break; /* * HWC adjusts MDP layer alignment after query_valid_layer. * This makes the decision of layering rule unreliable. Thus we * add constraint to avoid frame_cfg becoming scale-down. * * TODO: If HWC adjusts MDP layer alignment before * query_valid_layer, we could remove this if statement. */ if ((has_layer_cap(c, MDP_RSZ_LAYER) || has_layer_cap(c, MDP_ROT_LAYER)) && (c->dst_width - c->src_width <= MDP_ALIGNMENT_MARGIN || c->dst_height - c->src_height <= MDP_ALIGNMENT_MARGIN)) break; //if greater than one layer need check ratio is same if ((i == 0 && !*has_dim_layer) || (i == 1 && *has_dim_layer)) basic_layer = c; else if (!same_ratio(basic_layer, c)) break; else if (same_ratio_limitation(c, RATIO_LIMIT)) break; rect_make(&src_layer_roi, (c->dst_offset_x * c->src_width) / c->dst_width, (c->dst_offset_y * c->src_height) / c->dst_height, c->src_width, c->src_height); rect_join(&src_layer_roi, &src_total_roi, &src_total_roi); rect_make(&dst_layer_roi, c->dst_offset_x, c->dst_offset_y, c->dst_width, c->dst_height); rect_join(&dst_layer_roi, &dst_total_roi, &dst_total_roi); if (src_total_roi.width > dst_total_roi.width || src_total_roi.height > dst_total_roi.height) { DISPERR("layer%d RSZ scale-down src(%d, %d, %d, %d)\n", i, src_layer_roi.x, src_layer_roi.y, src_layer_roi.width, src_layer_roi.height); DISPERR("layer%d RSZ scale-down dst(%d, %d, %d, %d)\n", i, dst_layer_roi.x, dst_layer_roi.y, dst_layer_roi.width, dst_layer_roi.height); break; } if (src_total_roi.width > RSZ_TILE_LENGTH - RSZ_ALIGNMENT_MARGIN || src_total_roi.height > RSZ_IN_MAX_HEIGHT) break; c->layer_caps |= DISP_RSZ_LAYER; *rsz_idx = i; } if (*rsz_idx == -1) return false; for (i = *rsz_idx + 1; i < disp_info->layer_num[disp_idx]; i++) { c = &disp_info->input_config[disp_idx][i]; if (c->src_width != c->dst_width || c->src_height != c->dst_height) { if (has_layer_cap(c, MDP_RSZ_LAYER)) continue; gpu_rsz_idx = i; break; } } if (gpu_rsz_idx) rollback_resize_layer_to_GPU_range(disp_info, disp_idx, gpu_rsz_idx, disp_info->layer_num[disp_idx] - 1); return true; } static bool lr_rsz_layout(struct disp_layer_info *disp_info) { int disp_idx; if (is_ext_path(disp_info)) rollback_all_resize_layer_to_GPU(disp_info, HRT_SECONDARY); for (disp_idx = 0; disp_idx < 2; disp_idx++) { int rsz_idx = 0; bool has_dim_layer = false; if (disp_info->layer_num[disp_idx] <= 0) continue; /* only support resize layer on Primary Display */ if (disp_idx == HRT_SECONDARY) continue; if (!has_rsz_layer(disp_info, disp_idx)) { l_rule_info.scale_rate = HRT_SCALE_NONE; l_rule_info.disp_path = HRT_PATH_UNKNOWN; } else if (is_RPO(disp_info, disp_idx, &rsz_idx, &has_dim_layer)) { if (rsz_idx == 0) l_rule_info.disp_path = HRT_PATH_RPO_L0; else if (rsz_idx == 1 && has_dim_layer) l_rule_info.disp_path = HRT_PATH_RPO_DIM_L0; else if (rsz_idx != -1) l_rule_info.disp_path = HRT_PATH_RPO_BOTH; } else { rollback_all_resize_layer_to_GPU(disp_info, HRT_PRIMARY); l_rule_info.scale_rate = HRT_SCALE_NONE; l_rule_info.disp_path = HRT_PATH_UNKNOWN; } } return 0; } static bool lr_unset_disp_rsz_attr(struct disp_layer_info *disp_info, int disp_idx) { struct layer_config *lc = &disp_info->input_config[disp_idx][0]; if (l_rule_info.disp_path == HRT_PATH_RPO_L0 && has_layer_cap(lc, MDP_RSZ_LAYER) && has_layer_cap(lc, DISP_RSZ_LAYER)) { lc->layer_caps &= ~DISP_RSZ_LAYER; l_rule_info.disp_path = HRT_PATH_GENERAL; l_rule_info.layer_tb_idx = HRT_TB_TYPE_GENERAL; return true; } return false; } static void lr_gpu_change_rsz_info(void) { } static void layering_rule_senario_decision(struct disp_layer_info *disp_info) { mmprofile_log_ex(ddp_mmp_get_events()->hrt, MMPROFILE_FLAG_START, l_rule_info.disp_path, l_rule_info.layer_tb_idx | (l_rule_info.bound_tb_idx << 16)); if (GET_SYS_STATE(DISP_HRT_MULTI_TUI_ON)) { l_rule_info.disp_path = HRT_PATH_GENERAL; /* layer_tb_idx = HRT_TB_TYPE_MULTI_WINDOW_TUI;*/ l_rule_info.layer_tb_idx = HRT_TB_TYPE_GENERAL; } else { if (l_rule_info.disp_path == HRT_PATH_RPO_L0) { l_rule_info.layer_tb_idx = HRT_TB_TYPE_RPO_L0; } else if (l_rule_info.disp_path == HRT_PATH_RPO_DIM_L0) { l_rule_info.layer_tb_idx = HRT_TB_TYPE_RPO_DIM_L0; } else if (l_rule_info.disp_path == HRT_PATH_RPO_BOTH) { l_rule_info.layer_tb_idx = HRT_TB_TYPE_RPO_BOTH; } else { l_rule_info.layer_tb_idx = HRT_TB_TYPE_GENERAL; l_rule_info.disp_path = HRT_PATH_GENERAL; } } l_rule_info.primary_fps = 60; #if defined(CONFIG_MTK_DRAMC) && 0 if (get_ddr_type() == TYPE_LPDDR3) { if (primary_display_get_width() < 800) { if (primary_display_get_height() < 1500) /* LP3 HD & HD+(<=18:9) */ l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP3_HD; else /* LP3 HD+(>18:9) */ l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP3_HD_PLUS; } else { if (primary_display_get_height() < 2200) /* LP3 FHD & FHD+(<=18:9) */ l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP3; else /* LP3 FHD+(>18:9) */ l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP3_PLUS; } } else { /* LPDDR4, LPDDR4X */ if (primary_display_get_width() < 800) { if (primary_display_get_height() < 1500) { /* LP4 HD & HD+(<=18:9) */ if (get_emi_ch_num() == 2) l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP4_HD; else l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP3_HD; } else { /* LP4 HD+(>18:9) */ if (get_emi_ch_num() == 2) l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP4_HD_PLUS; else l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP3_HD_PLUS; } } else { if (primary_display_get_height() < 2200) { /* LP4 FHD & FHD+(<=18:9) */ if (get_emi_ch_num() == 2) l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP4; else l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP4_1CH; } else { /* LP4 FHD+(>18:9) */ if (get_emi_ch_num() == 2) l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP4_PLUS; else l_rule_info.bound_tb_idx = HRT_BOUND_TYPE_LP3_PLUS; } } } #endif mmprofile_log_ex(ddp_mmp_get_events()->hrt, MMPROFILE_FLAG_END, l_rule_info.disp_path, l_rule_info.layer_tb_idx | (l_rule_info.bound_tb_idx << 16)); } static bool filter_by_yuv_layers(struct disp_layer_info *disp_info) { bool flag = false; unsigned int disp_idx = 0, i = 0; struct layer_config *info; unsigned int yuv_cnt = 0; for (disp_idx = 0; disp_idx < 2; disp_idx++) { yuv_cnt = 0; for (i = 0; i < disp_info->layer_num[disp_idx]; i++) { info = &(disp_info->input_config[disp_idx][i]); if (is_gles_layer(disp_info, disp_idx, i)) continue; /* display not support RGBA1010102 & RGBA_FP16 */ if (info->src_fmt == DISP_FORMAT_RGBA1010102 || info->src_fmt == DISP_FORMAT_RGBA_FP16) { rollback_layer_to_GPU(disp_info, disp_idx, i); flag = true; continue; } /* ovl support total 1 yuv layer ,align to mt6853*/ if (is_yuv(info->src_fmt)) { yuv_cnt++; if (yuv_cnt > 1) { rollback_layer_to_GPU(disp_info, disp_idx, i); flag = true; } } } } return flag; } static bool filter_by_sec_display(struct disp_layer_info *disp_info) { bool flag = false; unsigned int i, layer_cnt = 0; for (i = 0; i < disp_info->layer_num[HRT_SECONDARY]; i++) { if (is_gles_layer(disp_info, HRT_SECONDARY, i)) continue; layer_cnt++; if (layer_cnt > SECONDARY_OVL_LAYER_NUM) { rollback_layer_to_GPU(disp_info, HRT_SECONDARY, i); flag = true; } } return flag; } static bool filter_by_hw_limitation(struct disp_layer_info *disp_info) { bool flag = false; flag |= filter_by_yuv_layers(disp_info); flag |= filter_by_sec_display(disp_info); return flag; } unsigned int layering_rule_get_hrt_idx(void) { return l_rule_info.hrt_idx; } static void clear_layer(struct disp_layer_info *disp_info) { int di = 0; int i = 0; struct layer_config *c; for (di = 0; di < 2; di++) { int g_head = disp_info->gles_head[di]; int top = -1; if (disp_info->layer_num[di] <= 0) continue; if (g_head == -1) continue; for (i = disp_info->layer_num[di] - 1; i >= g_head; i--) { c = &disp_info->input_config[di][i]; if (has_layer_cap(c, LAYERING_OVL_ONLY) && has_layer_cap(c, CLIENT_CLEAR_LAYER)) { top = i; break; } } if (top == -1) continue; if (!is_gles_layer(disp_info, di, top)) continue; c = &disp_info->input_config[di][top]; c->layer_caps |= DISP_CLIENT_CLEAR_LAYER; DISPMSG("%s:D%d:L%d\n", __func__, di, top); disp_info->gles_head[di] = 0; disp_info->gles_tail[di] = disp_info->layer_num[di] - 1; for (i = 0; i < disp_info->layer_num[di]; i++) { c = &disp_info->input_config[di][i]; c->ext_sel_layer = -1; if (i == top) c->ovl_id = 0; else c->ovl_id = 1; } } } static int get_hrt_bound(int is_larb, int hrt_level) { if (is_larb) return larb_bound_table[l_rule_info.bound_tb_idx][hrt_level]; else return emi_bound_table[l_rule_info.bound_tb_idx][hrt_level]; } static int *get_bound_table(enum DISP_HW_MAPPING_TB_TYPE tb_type) { switch (tb_type) { case DISP_HW_EMI_BOUND_TB: return emi_bound_table[l_rule_info.bound_tb_idx]; case DISP_HW_LARB_BOUND_TB: return larb_bound_table[l_rule_info.bound_tb_idx]; default: return NULL; } } static int get_mapping_table(enum DISP_HW_MAPPING_TB_TYPE tb_type, int param) { int layer_tb_idx = l_rule_info.layer_tb_idx; switch (tb_type) { case DISP_HW_OVL_TB: return ovl_mapping_table[layer_tb_idx]; case DISP_HW_LARB_TB: return larb_mapping_table[layer_tb_idx]; case DISP_HW_LAYER_TB: if (param < MAX_PHY_OVL_CNT && param >= 0) return layer_mapping_table[layer_tb_idx][param]; else return -1; default: return -1; } } #ifdef CONFIG_MTK_HIGH_FRAME_RATE #ifdef MTK_FB_MMDVFS_SUPPORT int layering_get_valid_hrt(int active_config_id) { #ifdef CONFIG_ARM64 unsigned long long dvfs_bw; unsigned long long tmp; #else unsigned int dvfs_bw; unsigned int tmp; #endif int tmp_bw; tmp_bw = mm_hrt_get_available_hrt_bw(get_virtual_port(VIRTUAL_DISP)); tmp = layering_get_frame_bw(active_config_id); if (tmp_bw < 0) { DISPERR("avail BW less than 0,DRAMC not ready!\n"); dvfs_bw = 200; goto done; } dvfs_bw = 10000 * tmp_bw; dvfs_bw /= tmp * 100; /* error handling when requested BW is less than 2 layers */ if (dvfs_bw < 200) { disp_aee_print("avail BW less than 2 layers, BW: %llu\n", dvfs_bw); dvfs_bw = 200; } done: DISPINFO( "get avail HRT BW:%u : %llu %llu\n", mm_hrt_get_available_hrt_bw( get_virtual_port(VIRTUAL_DISP)), dvfs_bw, tmp); return dvfs_bw; } #endif unsigned long long layering_get_frame_bw(int active_cfg_id) { #ifdef CONFIG_ARM64 static unsigned long long bw_base; #else static unsigned int bw_base; #endif unsigned int timing_fps = 60; #ifdef CONFIG_MTK_HIGH_FRAME_RATE unsigned int _vact_timing_FPS = 6000;/*real fps * 100*/ #endif if (bw_base) return bw_base; #ifdef CONFIG_MTK_HIGH_FRAME_RATE /* should use the real timing fps such as VFP solution*/ primary_display_get_cfg_fps( active_cfg_id, NULL, &_vact_timing_FPS); timing_fps = _vact_timing_FPS / 100; #endif /*ToDo: Resolution switch *if resolution changed also need change bw_base */ bw_base = (unsigned long long) primary_display_get_width() * primary_display_get_height() * timing_fps * 125 * 4; bw_base /= 100 * 1024 * 1024; return bw_base; } #endif int set_emi_bound_tb(int idx, int num, int *val) { int i; if (idx >= HRT_BOUND_NUM || idx < 0) return -EINVAL; if (num > HRT_LEVEL_NUM) return -EINVAL; for (i = 0; i < num; i++) emi_bound_table[idx][i] = val[i]; return 0; } void layering_rule_init(void) { int opt = 0; l_rule_info.primary_fps = 60; register_layering_rule_ops(&l_rule_ops, &l_rule_info); opt = disp_helper_get_option(DISP_OPT_RPO); if (opt != -1) set_layering_opt(LYE_OPT_RPO, opt); opt = disp_helper_get_option(DISP_OPT_OVL_EXT_LAYER); if (opt != -1) set_layering_opt(LYE_OPT_EXT_LAYER, opt); } int layering_rule_get_mm_freq_table(enum HRT_OPP_LEVEL opp_level) { enum HRT_DRAMC_TYPE dramc_type = HRT_DRAMC_TYPE_LP4_3733; if (opp_level == HRT_OPP_LEVEL_DEFAULT) { DISPINFO("skip opp level=%d\n", opp_level); return 0; } else if (opp_level > HRT_OPP_LEVEL_DEFAULT) { DISPERR("unsupport opp level=%d\n", opp_level); return 0; } #if defined(CONFIG_MTK_DRAMC) && 0 if (get_ddr_type() == TYPE_LPDDR3) dramc_type = HRT_DRAMC_TYPE_LP3; else { /* LPDDR4-3733, LPDDR4-3200 */ if (dram_steps_freq(0) == 3600) dramc_type = HRT_DRAMC_TYPE_LP4_3733; else dramc_type = HRT_DRAMC_TYPE_LP4_3200; } #endif mmprofile_log_ex(ddp_mmp_get_events()->dvfs, MMPROFILE_FLAG_PULSE, dramc_type, opp_level); return mm_freq_table[dramc_type][opp_level]; } static struct layering_rule_ops l_rule_ops = { .resizing_rule = lr_rsz_layout, .rsz_by_gpu_info_change = lr_gpu_change_rsz_info, .scenario_decision = layering_rule_senario_decision, .get_bound_table = get_bound_table, .get_hrt_bound = get_hrt_bound, .get_mapping_table = get_mapping_table, .rollback_to_gpu_by_hw_limitation = filter_by_hw_limitation, .unset_disp_rsz_attr = lr_unset_disp_rsz_attr, .clear_layer = clear_layer, };