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

Commit 7f1e39e0 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm: sde: Check commit's validity when starting splash handoff"

parents fc98b97c b8e0c667
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -572,6 +572,7 @@ void sde_connector_complete_commit(struct drm_connector *connector)
{
	struct drm_device *dev;
	struct msm_drm_private *priv;
	struct sde_connector *c_conn;

	if (!connector) {
		SDE_ERROR("invalid connector\n");
@@ -584,11 +585,17 @@ void sde_connector_complete_commit(struct drm_connector *connector)
	/* signal connector's retire fence */
	sde_fence_signal(&to_sde_connector(connector)->retire_fence, 0);

	/* after first vsync comes,
	 * early splash resource should start to be released.
	/*
	 * After LK totally exits, LK's early splash resource
	 * should be released.
	 */
	if (sde_splash_get_lk_complete_status(priv->kms))
		sde_splash_free_resource(priv->kms, &priv->phandle);
	if (sde_splash_get_lk_complete_status(priv->kms)) {
		c_conn = to_sde_connector(connector);

		sde_splash_free_resource(priv->kms, &priv->phandle,
					c_conn->connector_type,
					c_conn->display);
	}

}

+4 −4
Original line number Diff line number Diff line
@@ -345,8 +345,8 @@ static void sde_kms_prepare_commit(struct msm_kms *kms,

	if (sde_kms->splash_info.handoff &&
		sde_kms->splash_info.display_splash_enabled)
		sde_splash_lk_stop_splash(kms);
	else
		sde_splash_lk_stop_splash(kms, state);

	sde_power_resource_enable(&priv->phandle,
			sde_kms->core_client, true);
}
+110 −24
Original line number Diff line number Diff line
@@ -313,6 +313,15 @@ static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms)
	kfree(event_string);
}

static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo,
					u32 *hdmi_cnt, u32 *dsi_cnt)
{
	mutex_lock(&sde_splash_lock);
	*hdmi_cnt = sinfo->hdmi_connector_cnt;
	*dsi_cnt = sinfo->dsi_connector_cnt;
	mutex_unlock(&sde_splash_lock);
}

static int _sde_splash_free_module_resource(struct msm_mmu *mmu,
				struct sde_splash_info *sinfo)
{
@@ -339,6 +348,29 @@ static int _sde_splash_free_module_resource(struct msm_mmu *mmu,
	return 0;
}

static bool _sde_splash_validate_commit(struct sde_kms *sde_kms,
					struct drm_atomic_state *state)
{
	int i, nplanes;
	struct drm_plane *plane;
	struct drm_device *dev = sde_kms->dev;

	nplanes = dev->mode_config.num_total_plane;

	for (i = 0; i < nplanes; i++) {
		plane = state->planes[i];

		/*
		 * As plane state has been swapped, we need to check
		 * fb in state->planes, not fb in state->plane_state.
		 */
		if (plane && plane->fb)
			return true;
	}

	return false;
}

__ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms)
{
	struct sde_kms *sde_kms;
@@ -369,8 +401,7 @@ __ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms)
			sde_power_data_bus_bandwidth_ctrl(phandle,
					sde_kms->core_client, false);

			ret = -EINVAL;
			break;
			return -EINVAL;
		}
	}

@@ -716,11 +747,17 @@ bool sde_splash_get_lk_complete_status(struct msm_kms *kms)
}

int sde_splash_free_resource(struct msm_kms *kms,
			struct sde_power_handle *phandle)
			struct sde_power_handle *phandle,
			int connector_type, void *display)
{
	struct sde_kms *sde_kms;
	struct sde_splash_info *sinfo;
	struct msm_mmu *mmu;
	struct dsi_display *dsi_display = display;
	int ret = 0;
	int hdmi_conn_count = 0;
	int dsi_conn_count = 0;
	static const char *last_commit_display_type = "unknown";

	if (!phandle || !kms) {
		SDE_ERROR("invalid phandle/kms.\n");
@@ -734,12 +771,21 @@ int sde_splash_free_resource(struct msm_kms *kms,
		return -EINVAL;
	}

	/* Get connector number where the early splash in on. */
	_sde_splash_get_connector_ref_cnt(sinfo, &hdmi_conn_count,
						&dsi_conn_count);

	mutex_lock(&sde_splash_lock);
	if (!sinfo->handoff) {
		mutex_unlock(&sde_splash_lock);
		return 0;
	}

	/*
	 * Start to free all LK's resource till user commit happens
	 * on each display which early splash is enabled on.
	 */
	if (hdmi_conn_count == 0 && dsi_conn_count == 0) {
		mmu = sde_kms->aspace[0]->mmu;
		if (!mmu) {
			mutex_unlock(&sde_splash_lock);
@@ -759,24 +805,63 @@ int sde_splash_free_resource(struct msm_kms *kms,
		sde_power_data_bus_bandwidth_ctrl(phandle,
					sde_kms->core_client, false);

		/*
		 * Turn off MDP core power to keep power on/off operations
		 * be matched, as MDP core power is enabled already when
		 * early splash is enabled.
		 */
		sde_power_resource_enable(phandle,
					sde_kms->core_client, false);

		/* send uevent to notify user to recycle resource */
		_sde_splash_sent_pipe_update_uevent(sde_kms);

	/* Finally mark handoff flag to false to say handoff is complete */
		/* Finally mark handoff flag to false to say
		 * handoff is complete.
		 */
		sinfo->handoff = false;

		DRM_INFO("HDMI and DSI resource handoff is completed\n");

		mutex_unlock(&sde_splash_lock);
		return 0;
	}

	/*
	 * Ensure user commit happens on different connectors
	 * who has splash.
	 */
	switch (connector_type) {
	case DRM_MODE_CONNECTOR_HDMIA:
		if (sinfo->hdmi_connector_cnt == 1)
			sinfo->hdmi_connector_cnt--;
		break;
	case DRM_MODE_CONNECTOR_DSI:
		if (strcmp(dsi_display->display_type, "unknown") &&
			strcmp(last_commit_display_type,
				dsi_display->display_type)) {
			if (sinfo->dsi_connector_cnt >= 1)
				sinfo->dsi_connector_cnt--;

			last_commit_display_type = dsi_display->display_type;
		}
		break;
	default:
		ret = -EINVAL;
		SDE_ERROR("%s: invalid connector_type %d\n",
					__func__, connector_type);
	}

	mutex_unlock(&sde_splash_lock);
	return ret;
}

/*
 * In below function, it will
 * 1. Notify LK to stop display splash.
 * 2. Set DOMAIN_ATTR_EARLY_MAP to 1 to enable stage 1 translation in iommu.
 */
int sde_splash_lk_stop_splash(struct msm_kms *kms)
int sde_splash_lk_stop_splash(struct msm_kms *kms,
				struct drm_atomic_state *state)
{
	struct sde_splash_info *sinfo;
	struct msm_mmu *mmu;
@@ -792,7 +877,8 @@ int sde_splash_lk_stop_splash(struct msm_kms *kms)

	/* Monitor LK's status and tell it to exit. */
	mutex_lock(&sde_splash_lock);
	if (sinfo->display_splash_enabled) {
	if (_sde_splash_validate_commit(sde_kms, state) &&
			sinfo->display_splash_enabled) {
		if (_sde_splash_lk_check(sde_kms->hw_intr))
			_sde_splash_notify_lk_stop_splash(sde_kms->hw_intr);

+12 −12
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@
#include "msm_mmu.h"
#include "sde_hw_mdss.h"

#define SPLASH_CTL_MAX 5
#define SPLASH_LM_MAX 7

enum splash_connector_type {
	SPLASH_DSI = 0,
	SPLASH_HDMI,
@@ -35,13 +32,13 @@ struct splash_ctl_top {
	u32 value;
	u8 intf_sel;
	u8 ctl_lm_cnt;
	struct splash_lm_hw lm[SPLASH_LM_MAX];
	struct splash_lm_hw lm[LM_MAX - LM_0];
};

struct sde_res_data {
	struct splash_ctl_top top[SPLASH_CTL_MAX];
	u8 ctl_ids[SPLASH_CTL_MAX];
	u8 lm_ids[SPLASH_LM_MAX];
	struct splash_ctl_top top[CTL_MAX - CTL_0];
	u8 ctl_ids[CTL_MAX - CTL_0];
	u8 lm_ids[LM_MAX - LM_0];
	u8 ctl_top_cnt;
	u8 lm_cnt;
};
@@ -121,18 +118,21 @@ void sde_splash_setup_connector_count(struct sde_splash_info *sinfo,
/**
 * sde_splash_lk_stop_splash.
 *
 * Tell LK to stop display splash.
 * Tell LK to stop display splash once one valid user commit arrives.
 */
int sde_splash_lk_stop_splash(struct msm_kms *kms);
int sde_splash_lk_stop_splash(struct msm_kms *kms,
				struct drm_atomic_state *state);

/**
 * sde_splash_free_resource.
 *
 * According to input connector_type, free
 * HDMI's and DSI's resource respectively.
 * To free all LK's resource, including free reserved memory to system,
 * withdraw data bus vote, disable MDP core power, send uevent to user
 * to recycle pipe etc.
 */
int sde_splash_free_resource(struct msm_kms *kms,
			struct sde_power_handle *phandle);
			struct sde_power_handle *phandle,
			int connector_type, void *display);

/**
 * sde_splash_parse_memory_dt.