Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8e8e40b6 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm/sde: add checks for linewidth and bwlimit"

parents 545fbae4 aad5ed99
Loading
Loading
Loading
Loading
+47 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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 =
@@ -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 =
@@ -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++;
	}
@@ -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)
@@ -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;
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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
 */
@@ -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;
};
@@ -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
@@ -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;
+36 −1
Original line number Diff line number Diff line
@@ -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,
@@ -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);