Loading msm/sde/sde_hw_catalog.c +47 −5 Original line number Diff line number Diff line Loading @@ -1196,7 +1196,8 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, sde_cfg->true_inline_dwnscale_rt_denom; sblk->in_rot_maxdwnscale_nrt = sde_cfg->true_inline_dwnscale_nrt; sblk->in_rot_maxheight = sblk->in_rot_maxheight = sde_cfg->inline_linewidth ? sde_cfg->inline_linewidth : MAX_PRE_ROT_HEIGHT_INLINE_ROT_DEFAULT; sblk->in_rot_prefill_fudge_lines = sde_cfg->true_inline_prefill_fudge_lines; Loading Loading @@ -3173,6 +3174,8 @@ static int sde_read_limit_node(struct device_node *snp, int j, i = 0, rc = 0; const char *type = NULL; struct device_node *node = NULL; u32 vig = 0, dma = 0, inline_rot = 0, scaling = 0; u32 usecase = 0, val = 0; for_each_child_of_node(snp, node) { cfg->limit_cfg[i].vector_cfg = Loading @@ -3191,6 +3194,16 @@ static int sde_read_limit_node(struct device_node *snp, cfg->limit_cfg[i].vector_cfg[j].value = PROP_VALUE_ACCESS(&lmt_val[i * LIMIT_PROP_MAX], LIMIT_ID, j); if (!strcmp(type, "vig")) vig = cfg->limit_cfg[i].vector_cfg[j].value; else if (!strcmp(type, "dma")) dma = cfg->limit_cfg[i].vector_cfg[j].value; else if (!strcmp(type, "inline_rot")) inline_rot = cfg->limit_cfg[i].vector_cfg[j].value; else if (!strcmp(type, "scale")) scaling = cfg->limit_cfg[i].vector_cfg[j].value; } cfg->limit_cfg[i].value_cfg = Loading @@ -3211,7 +3224,24 @@ static int sde_read_limit_node(struct device_node *snp, PROP_BITVALUE_ACCESS( &lmt_val[i * LIMIT_PROP_MAX], LIMIT_VALUE, j, 1); cfg->limit_cfg[i].max_value = max(cfg->limit_cfg[i].max_value, cfg->limit_cfg[i].value_cfg[j].value); usecase = cfg->limit_cfg[i].value_cfg[j].use_concur; val = cfg->limit_cfg[i].value_cfg[j].value; if (!strcmp(cfg->limit_cfg[i].name, "sspp_linewidth_usecases")) { if (usecase == dma) cfg->max_sspp_linewidth = val; else if (usecase == vig) cfg->vig_sspp_linewidth = val; else if (usecase == (vig | inline_rot)) cfg->inline_linewidth = val; else if (usecase == (vig | scaling)) cfg->scaling_linewidth = val; } } i++; } Loading Loading @@ -3421,6 +3451,8 @@ static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) cfg->pipe_order_type = PROP_VALUE_ACCESS(prop_value, PIPE_ORDER_VERSION, 0); cfg->has_base_layer = PROP_VALUE_ACCESS(prop_value, BASE_LAYER, 0); cfg->scaling_linewidth = 0; cfg->inline_linewidth = MAX_PRE_ROT_HEIGHT_INLINE_ROT_DEFAULT; rc = sde_limit_parse_dt(np, cfg); if (rc) Loading Loading @@ -4274,7 +4306,7 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) { int rc = 0, i; u32 max_horz_deci = 0, max_vert_deci = 0; u32 max_horz_deci = 0, max_vert_deci = 0, max_linewidth = 0; if (!sde_cfg) return -EINVAL; Loading Loading @@ -4309,9 +4341,19 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg, /* this should be updated based on HW rev in future */ sde_cfg->max_lm_per_display = MAX_LM_PER_DISPLAY; for (i = 0; i < sde_cfg->limit_count; i++) { if (!strcmp(sde_cfg->limit_cfg[i].name, "sspp_linewidth_usecases")) max_linewidth = sde_cfg->limit_cfg[i].max_value; else if (!strcmp(sde_cfg->limit_cfg[i].name, "sde_bwlimit_usecases")) sde_cfg->perf.max_bw_high = sde_cfg->limit_cfg[i].max_value; } if (max_horz_deci) sde_cfg->max_display_width = sde_cfg->max_sspp_linewidth * max_horz_deci; sde_cfg->max_display_width = (max_linewidth ? max_linewidth : sde_cfg->max_sspp_linewidth) * max_horz_deci; else sde_cfg->max_display_width = sde_cfg->max_sspp_linewidth * MAX_DOWNSCALE_RATIO; Loading msm/sde/sde_hw_catalog.h +6 −0 Original line number Diff line number Diff line Loading @@ -1209,6 +1209,7 @@ struct limit_value_cfg { * @name: name of the limit property * @lmt_vec_cnt: number of vector values for each limit * @lmt_case_cnt: number of usecases for each limit * @max_value: maximum possible value for this property * @vector_cfg: pointer to the vector entries containing info on usecase * @value_cfg: pointer to the value of each vector entry */ Loading @@ -1216,6 +1217,7 @@ struct sde_limit_cfg { const char *name; u32 lmt_vec_cnt; u32 lmt_case_cnt; u32 max_value; struct limit_vector_cfg *vector_cfg; struct limit_value_cfg *value_cfg; }; Loading @@ -1228,6 +1230,8 @@ struct sde_limit_cfg { * * @max_sspp_linewidth max source pipe line width support. * @vig_sspp_linewidth max vig source pipe line width support. * @scaling_linewidth max vig source pipe linewidth for scaling usecases * @inline_linewidth max source pipe linewidth for inline rotation * @max_mixer_width max layer mixer line width support. * @max_mixer_blendstages max layer mixer blend stages or * supported z order Loading Loading @@ -1298,6 +1302,8 @@ struct sde_mdss_cfg { u32 max_sspp_linewidth; u32 vig_sspp_linewidth; u32 scaling_linewidth; u32 inline_linewidth; u32 max_mixer_width; u32 max_mixer_blendstages; u32 max_wb_linewidth; Loading msm/sde/sde_plane.c +36 −1 Original line number Diff line number Diff line Loading @@ -2394,6 +2394,36 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, return 0; } static int sde_get_sspp_linewidth(struct sde_plane *psde, struct drm_plane_state *state, struct sde_rect *src, struct sde_rect *dst) { struct sde_plane_state *pstate; struct sde_kms *kms; u32 src_deci_w = 0, src_deci_h = 0, deci_w = 0, deci_h = 0; pstate = to_sde_plane_state(state); kms = _sde_plane_get_kms(&psde->base); if (!kms || !kms->catalog) return -EINVAL; if (!kms->catalog->scaling_linewidth) return psde->pipe_sblk->maxlinewidth; deci_w = sde_plane_get_property(pstate, PLANE_PROP_H_DECIMATE); deci_h = sde_plane_get_property(pstate, PLANE_PROP_V_DECIMATE); src_deci_w = DECIMATED_DIMENSION(src->w, deci_w); src_deci_h = DECIMATED_DIMENSION(src->h, deci_h); if ((src->w != state->crtc_w) || (src->h != state->crtc_h) || (src_deci_w != state->crtc_w) || (src_deci_h != state->crtc_h)) return kms->catalog->scaling_linewidth; else return psde->pipe_sblk->maxlinewidth; } static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, struct sde_plane *psde, const struct sde_format *fmt, struct sde_plane_state *pstate, struct sde_rect *src, Loading Loading @@ -2430,7 +2460,12 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, } max_upscale = psde->pipe_sblk->maxupscale; max_linewidth = psde->pipe_sblk->maxlinewidth; max_linewidth = sde_get_sspp_linewidth(psde, state, src, dst); if (max_linewidth <= 0) { SDE_ERROR("Invalid max linewidth\n"); return -EINVAL; } crtc = state->crtc; new_cstate = drm_atomic_get_new_crtc_state(state->state, crtc); Loading Loading
msm/sde/sde_hw_catalog.c +47 −5 Original line number Diff line number Diff line Loading @@ -1196,7 +1196,8 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, sde_cfg->true_inline_dwnscale_rt_denom; sblk->in_rot_maxdwnscale_nrt = sde_cfg->true_inline_dwnscale_nrt; sblk->in_rot_maxheight = sblk->in_rot_maxheight = sde_cfg->inline_linewidth ? sde_cfg->inline_linewidth : MAX_PRE_ROT_HEIGHT_INLINE_ROT_DEFAULT; sblk->in_rot_prefill_fudge_lines = sde_cfg->true_inline_prefill_fudge_lines; Loading Loading @@ -3173,6 +3174,8 @@ static int sde_read_limit_node(struct device_node *snp, int j, i = 0, rc = 0; const char *type = NULL; struct device_node *node = NULL; u32 vig = 0, dma = 0, inline_rot = 0, scaling = 0; u32 usecase = 0, val = 0; for_each_child_of_node(snp, node) { cfg->limit_cfg[i].vector_cfg = Loading @@ -3191,6 +3194,16 @@ static int sde_read_limit_node(struct device_node *snp, cfg->limit_cfg[i].vector_cfg[j].value = PROP_VALUE_ACCESS(&lmt_val[i * LIMIT_PROP_MAX], LIMIT_ID, j); if (!strcmp(type, "vig")) vig = cfg->limit_cfg[i].vector_cfg[j].value; else if (!strcmp(type, "dma")) dma = cfg->limit_cfg[i].vector_cfg[j].value; else if (!strcmp(type, "inline_rot")) inline_rot = cfg->limit_cfg[i].vector_cfg[j].value; else if (!strcmp(type, "scale")) scaling = cfg->limit_cfg[i].vector_cfg[j].value; } cfg->limit_cfg[i].value_cfg = Loading @@ -3211,7 +3224,24 @@ static int sde_read_limit_node(struct device_node *snp, PROP_BITVALUE_ACCESS( &lmt_val[i * LIMIT_PROP_MAX], LIMIT_VALUE, j, 1); cfg->limit_cfg[i].max_value = max(cfg->limit_cfg[i].max_value, cfg->limit_cfg[i].value_cfg[j].value); usecase = cfg->limit_cfg[i].value_cfg[j].use_concur; val = cfg->limit_cfg[i].value_cfg[j].value; if (!strcmp(cfg->limit_cfg[i].name, "sspp_linewidth_usecases")) { if (usecase == dma) cfg->max_sspp_linewidth = val; else if (usecase == vig) cfg->vig_sspp_linewidth = val; else if (usecase == (vig | inline_rot)) cfg->inline_linewidth = val; else if (usecase == (vig | scaling)) cfg->scaling_linewidth = val; } } i++; } Loading Loading @@ -3421,6 +3451,8 @@ static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) cfg->pipe_order_type = PROP_VALUE_ACCESS(prop_value, PIPE_ORDER_VERSION, 0); cfg->has_base_layer = PROP_VALUE_ACCESS(prop_value, BASE_LAYER, 0); cfg->scaling_linewidth = 0; cfg->inline_linewidth = MAX_PRE_ROT_HEIGHT_INLINE_ROT_DEFAULT; rc = sde_limit_parse_dt(np, cfg); if (rc) Loading Loading @@ -4274,7 +4306,7 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) { int rc = 0, i; u32 max_horz_deci = 0, max_vert_deci = 0; u32 max_horz_deci = 0, max_vert_deci = 0, max_linewidth = 0; if (!sde_cfg) return -EINVAL; Loading Loading @@ -4309,9 +4341,19 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg, /* this should be updated based on HW rev in future */ sde_cfg->max_lm_per_display = MAX_LM_PER_DISPLAY; for (i = 0; i < sde_cfg->limit_count; i++) { if (!strcmp(sde_cfg->limit_cfg[i].name, "sspp_linewidth_usecases")) max_linewidth = sde_cfg->limit_cfg[i].max_value; else if (!strcmp(sde_cfg->limit_cfg[i].name, "sde_bwlimit_usecases")) sde_cfg->perf.max_bw_high = sde_cfg->limit_cfg[i].max_value; } if (max_horz_deci) sde_cfg->max_display_width = sde_cfg->max_sspp_linewidth * max_horz_deci; sde_cfg->max_display_width = (max_linewidth ? max_linewidth : sde_cfg->max_sspp_linewidth) * max_horz_deci; else sde_cfg->max_display_width = sde_cfg->max_sspp_linewidth * MAX_DOWNSCALE_RATIO; Loading
msm/sde/sde_hw_catalog.h +6 −0 Original line number Diff line number Diff line Loading @@ -1209,6 +1209,7 @@ struct limit_value_cfg { * @name: name of the limit property * @lmt_vec_cnt: number of vector values for each limit * @lmt_case_cnt: number of usecases for each limit * @max_value: maximum possible value for this property * @vector_cfg: pointer to the vector entries containing info on usecase * @value_cfg: pointer to the value of each vector entry */ Loading @@ -1216,6 +1217,7 @@ struct sde_limit_cfg { const char *name; u32 lmt_vec_cnt; u32 lmt_case_cnt; u32 max_value; struct limit_vector_cfg *vector_cfg; struct limit_value_cfg *value_cfg; }; Loading @@ -1228,6 +1230,8 @@ struct sde_limit_cfg { * * @max_sspp_linewidth max source pipe line width support. * @vig_sspp_linewidth max vig source pipe line width support. * @scaling_linewidth max vig source pipe linewidth for scaling usecases * @inline_linewidth max source pipe linewidth for inline rotation * @max_mixer_width max layer mixer line width support. * @max_mixer_blendstages max layer mixer blend stages or * supported z order Loading Loading @@ -1298,6 +1302,8 @@ struct sde_mdss_cfg { u32 max_sspp_linewidth; u32 vig_sspp_linewidth; u32 scaling_linewidth; u32 inline_linewidth; u32 max_mixer_width; u32 max_mixer_blendstages; u32 max_wb_linewidth; Loading
msm/sde/sde_plane.c +36 −1 Original line number Diff line number Diff line Loading @@ -2394,6 +2394,36 @@ static int _sde_plane_validate_scaler_v2(struct sde_plane *psde, return 0; } static int sde_get_sspp_linewidth(struct sde_plane *psde, struct drm_plane_state *state, struct sde_rect *src, struct sde_rect *dst) { struct sde_plane_state *pstate; struct sde_kms *kms; u32 src_deci_w = 0, src_deci_h = 0, deci_w = 0, deci_h = 0; pstate = to_sde_plane_state(state); kms = _sde_plane_get_kms(&psde->base); if (!kms || !kms->catalog) return -EINVAL; if (!kms->catalog->scaling_linewidth) return psde->pipe_sblk->maxlinewidth; deci_w = sde_plane_get_property(pstate, PLANE_PROP_H_DECIMATE); deci_h = sde_plane_get_property(pstate, PLANE_PROP_V_DECIMATE); src_deci_w = DECIMATED_DIMENSION(src->w, deci_w); src_deci_h = DECIMATED_DIMENSION(src->h, deci_h); if ((src->w != state->crtc_w) || (src->h != state->crtc_h) || (src_deci_w != state->crtc_w) || (src_deci_h != state->crtc_h)) return kms->catalog->scaling_linewidth; else return psde->pipe_sblk->maxlinewidth; } static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, struct sde_plane *psde, const struct sde_format *fmt, struct sde_plane_state *pstate, struct sde_rect *src, Loading Loading @@ -2430,7 +2460,12 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state, } max_upscale = psde->pipe_sblk->maxupscale; max_linewidth = psde->pipe_sblk->maxlinewidth; max_linewidth = sde_get_sspp_linewidth(psde, state, src, dst); if (max_linewidth <= 0) { SDE_ERROR("Invalid max linewidth\n"); return -EINVAL; } crtc = state->crtc; new_cstate = drm_atomic_get_new_crtc_state(state->state, crtc); Loading