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

Commit a9c4cd21 authored by Sean Paul's avatar Sean Paul Committed by Inki Dae
Browse files

drm/exynos: Disable unused crtc planes from crtc



This patch moves the code which disables unused crtc planes from the
encoder to the crtc. Since there is a 1:1 encoder/crtc mapping in
exynos, the only valid crtc change the pre-existing code could catch is
disconnecting an active crtc from the encoder. Thus it is functionally
equivalent to just disable all planes attached to a crtc when the crtc
is disabled.

Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 75626853
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -176,10 +176,19 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,

static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct drm_plane *plane;
	int ret;

	exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_OFF);
	exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);

	list_for_each_entry(plane, &crtc->dev->mode_config.plane_list, head) {
		if (plane->crtc != crtc)
			continue;

		ret = plane->funcs->disable_plane(plane);
		if (ret)
			DRM_ERROR("Failed to disable plane %d\n", ret);
	}
}

static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
+4 −61
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@
 * @display: the display structure that maps to this encoder
 */
struct exynos_drm_encoder {
	struct drm_crtc			*old_crtc;
	struct drm_encoder		drm_encoder;
	struct exynos_drm_display	*display;
};
@@ -67,71 +66,15 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
	return true;
}

static void disable_plane_to_crtc(struct drm_device *dev,
						struct drm_crtc *old_crtc,
						struct drm_crtc *new_crtc)
{
	struct drm_plane *plane;

	/*
	 * if old_crtc isn't same as encoder->crtc then it means that
	 * user changed crtc id to another one so the plane to old_crtc
	 * should be disabled and plane->crtc should be set to new_crtc
	 * (encoder->crtc)
	 */
	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
		if (plane->crtc == old_crtc) {
			/*
			 * do not change below call order.
			 *
			 * plane->funcs->disable_plane call checks
			 * if encoder->crtc is same as plane->crtc and if same
			 * then manager_ops->win_disable callback will be called
			 * to diasble current hw overlay so plane->crtc should
			 * have new_crtc because new_crtc was set to
			 * encoder->crtc in advance.
			 */
			plane->crtc = new_crtc;
			plane->funcs->disable_plane(plane);
		}
	}
}

static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
					 struct drm_display_mode *mode,
					 struct drm_display_mode *adjusted_mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_connector *connector;
	struct exynos_drm_display *display;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		if (connector->encoder == encoder) {
			struct exynos_drm_encoder *exynos_encoder;

			exynos_encoder = to_exynos_encoder(encoder);

			if (exynos_encoder->old_crtc != encoder->crtc &&
					exynos_encoder->old_crtc) {

				/*
				 * disable a plane to old crtc and change
				 * crtc of the plane to new one.
				 */
				disable_plane_to_crtc(dev,
						exynos_encoder->old_crtc,
						encoder->crtc);
			}

			display = exynos_encoder->display;
	struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
	struct exynos_drm_display *display = exynos_encoder->display;

	if (display->ops->mode_set)
				display->ops->mode_set(display,
							adjusted_mode);

			exynos_encoder->old_crtc = encoder->crtc;
		}
	}
		display->ops->mode_set(display, adjusted_mode);
}

static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)