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

Commit 44c91697 authored by Inki Dae's avatar Inki Dae Committed by Inki Dae
Browse files

drm/exynos: fix display on issue



When crtc_funcs->dpms callback is called, exynos_crtc->dpms
and exynos_encoder->dpms are changed to new mode. But if user
requests dpms mode operation, OFF -> ON, when crtc's dpms callback
is called, exynos_encoder->dpms is also changed to ON. This
makes encoder's dpms callback call be ignored so display power
couldn't become on again.

This patch removes exynos_encoder->dpms changing and adds 'updated'
variable to exynos_drm_encoder structure to avoid duplicated overlay
updating.

Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
parent 4936b172
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -374,6 +374,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
	exynos_connector->encoder_id = encoder->base.id;
	exynos_connector->manager = manager;
	exynos_connector->dpms = DRM_MODE_DPMS_OFF;
	connector->dpms = DRM_MODE_DPMS_OFF;
	connector->encoder = encoder;

	err = drm_mode_connector_attach_encoder(connector, encoder);
+17 −16
Original line number Diff line number Diff line
@@ -43,12 +43,14 @@
 * @manager: specific encoder has its own manager to control a hardware
 *	appropriately and we can access a hardware drawing on this manager.
 * @dpms: store the encoder dpms value.
 * @updated: indicate whether overlay data updating is needed or not.
 */
struct exynos_drm_encoder {
	struct drm_crtc			*old_crtc;
	struct drm_encoder		drm_encoder;
	struct exynos_drm_manager	*manager;
	int				dpms;
	bool				updated;
};

static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
@@ -85,7 +87,9 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
	switch (mode) {
	case DRM_MODE_DPMS_ON:
		if (manager_ops && manager_ops->apply)
			if (!exynos_encoder->updated)
				manager_ops->apply(manager->dev);

		exynos_drm_connector_power(encoder, mode);
		exynos_encoder->dpms = mode;
		break;
@@ -94,6 +98,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
	case DRM_MODE_DPMS_OFF:
		exynos_drm_connector_power(encoder, mode);
		exynos_encoder->dpms = mode;
		exynos_encoder->updated = false;
		break;
	default:
		DRM_ERROR("unspecified mode %d\n", mode);
@@ -205,13 +210,22 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)

static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
{
	struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
	struct exynos_drm_manager *manager = exynos_encoder->manager;
	struct exynos_drm_manager_ops *manager_ops = manager->ops;

	DRM_DEBUG_KMS("%s\n", __FILE__);

	if (manager_ops && manager_ops->commit)
		manager_ops->commit(manager->dev);

	/*
	 * this will avoid one issue that overlay data is updated to
	 * real hardware two times.
	 * And this variable will be used to check if the data was
	 * already updated or not by exynos_drm_encoder_dpms function.
	 */
	exynos_encoder->updated = true;
}

static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
@@ -400,19 +414,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
	if (manager_ops && manager_ops->dpms)
		manager_ops->dpms(manager->dev, mode);

	/*
	 * set current mode to new one so that data aren't updated into
	 * registers by drm_helper_connector_dpms two times.
	 *
	 * in case that drm_crtc_helper_set_mode() is called,
	 * overlay_ops->commit() and manager_ops->commit() callbacks
	 * can be called two times, first at drm_crtc_helper_set_mode()
	 * and second at drm_helper_connector_dpms().
	 * so with this setting, when drm_helper_connector_dpms() is called
	 * encoder->funcs->dpms() will be ignored.
	 */
	exynos_encoder->dpms = mode;

	/*
	 * if this condition is ok then it means that the crtc is already
	 * detached from encoder and last function for detaching is properly