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

Commit 400afd14 authored by Nilaan Gunabalachandran's avatar Nilaan Gunabalachandran
Browse files

drm/msm/sde: dynamic layer mixer reservation for prim disp



SDE driver should not reserve multiple layer mixers for primary
display if target does not have sufficient layer mixers for
other displays. Such static reservation blocks higher resolution
display for non-primary display. This patch gets the layer mixer
requirement for primary DSI display if available. It reserves
those layer mixers dynamically for the primary display when
connector is registered. Primary layer mixer reservation falls
back to dtsi based support if connector ops are not implemented.

Change-Id: I2e7ccd0c68e1f10d458b10150c737aa0193cfec2
Signed-off-by: default avatarNilaan Gunabalachandran <ngunabal@codeaurora.org>
parent 1ae5de3f
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -5656,6 +5656,37 @@ int dsi_display_get_panel_vfp(void *dsi_display,
	return rc;
}

int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm)
{
	struct dsi_display *display = (struct dsi_display *)dsi_display;
	u32 count, i;
	int rc = 0;

	*num_lm = 0;

	rc = dsi_display_get_mode_count(display, &count);
	if (rc)
		return rc;

	if (!display->modes) {
		struct dsi_display_mode *m;

		rc = dsi_display_get_modes(display, &m);
		if (rc)
			return rc;
	}

	mutex_lock(&display->display_lock);
	for (i = 0; i < count; i++) {
		struct dsi_display_mode *m = &display->modes[i];

		*num_lm = max(m->priv_info->topology.num_lm, *num_lm);
	}
	mutex_unlock(&display->display_lock);

	return rc;
}

int dsi_display_find_mode(struct dsi_display *display,
		const struct dsi_display_mode *cmp,
		struct dsi_display_mode **out_mode)
+10 −0
Original line number Diff line number Diff line
@@ -375,6 +375,16 @@ int dsi_display_get_modes(struct dsi_display *display,
void dsi_display_put_mode(struct dsi_display *display,
	struct dsi_display_mode *mode);

/**
 * dsi_display_get_default_lms() - retrieve max number of lms used
 *             for dsi display by traversing through all topologies
 * @display:            Handle to display.
 * @num_lm:             Number of LMs used
 *
 * Return: error code.
 */
int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm);

/**
 * dsi_display_find_mode() - retrieve cached DSI mode given relevant params
 * @display:            Handle to display.
+32 −0
Original line number Diff line number Diff line
@@ -1524,6 +1524,35 @@ int sde_connector_helper_reset_custom_properties(
	return 0;
}

static int _sde_connector_primary_preference(struct sde_connector *sde_conn,
		struct sde_kms *sde_kms)
{
	int ret = 0;
	u32 num_lm = 0;

	if (!sde_conn || !sde_kms || !sde_conn->ops.get_default_lms) {
		SDE_DEBUG("invalid input params");
		return -EINVAL;
	}

	ret = sde_conn->ops.get_default_lms(sde_conn->display, &num_lm);
	if (ret || !num_lm) {
		SDE_DEBUG("failed to get default lm count");
		return ret;
	}

	if (num_lm > sde_kms->catalog->mixer_count) {
		SDE_DEBUG(
				"topology requesting more lms [%d] than hw exists [%d]",
				num_lm, sde_kms->catalog->mixer_count);
		return -EINVAL;
	}

	sde_hw_mixer_set_preference(sde_kms->catalog, num_lm);

	return ret;
}

int sde_connector_get_panel_vfp(struct drm_connector *connector,
	struct drm_display_mode *mode)
{
@@ -2411,6 +2440,9 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
		goto error_destroy_property;
	}

	if (display_info.is_primary)
		_sde_connector_primary_preference(c_conn, sde_kms);

	SDE_DEBUG("connector %d attach encoder %d\n",
			c_conn->base.base.id, encoder->base.id);

+8 −0
Original line number Diff line number Diff line
@@ -304,6 +304,14 @@ struct sde_connector_ops {
	 * Returns: v_front_porch on success error-code on failure
	 */
	int (*get_panel_vfp)(void *display, int h_active, int v_active);

	/**
	 * get_default_lm - returns default number of lm
	 * @display: Pointer to private display handle
	 * @num_lm: Pointer to number of lms to be populated
	 * Returns: zero for success, negetive for failure
	 */
	int (*get_default_lms)(void *display, u32 *num_lm);
};

/**
+13 −0
Original line number Diff line number Diff line
@@ -1603,6 +1603,19 @@ static int sde_ctl_parse_dt(struct device_node *np,
	return rc;
}

void sde_hw_mixer_set_preference(struct sde_mdss_cfg *sde_cfg, u32 num_lm)
{
	u32 i;

	for (i = 0; i < sde_cfg->mixer_count; i++) {
		clear_bit(SDE_DISP_PRIMARY_PREF,
				&sde_cfg->mixer[i].features);
		if (i < num_lm)
			set_bit(SDE_DISP_PRIMARY_PREF,
					&sde_cfg->mixer[i].features);
	}
}

static int sde_mixer_parse_dt(struct device_node *np,
						struct sde_mdss_cfg *sde_cfg)
{
Loading