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

Commit aad5ed99 authored by Krishna Manikandan's avatar Krishna Manikandan
Browse files

msm/sde: add checks for linewidth and bwlimit



Add checks to handle linewidth for scaling and inline
rotation based on the new node added in dt. Checks
for bw limits are also updated accordingly.

Change-Id: Ife584166d5859560bbd5a65958e796007985d9c2
Signed-off-by: default avatarKrishna Manikandan <mkrishn@codeaurora.org>
parent 7f7cf760
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);