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

Commit 8e9c1c66 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Tomi Valkeinen
Browse files

drm/omap: Move bus flag hack to encoder implementation



The bus flags stored in omap_dss_device instances are used to fixup the
video mode before setting it, to honour constraints that can't be
expressed through drm_display_mode. The fixup occurs in the CRTC mode
set operation and the resulting video mode is stored internally in the
CRTC. It is then used next by omap_encoder_enable() to apply mode fixups
for the omap_dss_device instances in omap_encoder_update().

Move the hack to the omap_encoder_update() function right before
applying the omap_dss_device fixups, in order to group all fixups
together.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 31cd7afa
Loading
Loading
Loading
Loading
+1 −41
Original line number Diff line number Diff line
@@ -420,8 +420,6 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
	struct videomode *vm = &omap_crtc->vm;
	struct omap_dss_device *dssdev;

	DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
	    omap_crtc->name, mode->base.id, mode->name,
@@ -430,45 +428,7 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
	    mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
	    mode->type, mode->flags);

	drm_display_mode_to_videomode(mode, vm);

	/*
	 * HACK: This fixes the vm flags.
	 * struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags
	 * and they get lost when converting back and forth between
	 * struct drm_display_mode and struct videomode. The hack below
	 * goes and fetches the missing flags from the panel drivers.
	 *
	 * A better solution is to use DRM's bus-flags through the whole driver.
	 */

	for (dssdev = omap_crtc->pipe->output; dssdev; dssdev = dssdev->next) {
		unsigned long bus_flags = dssdev->bus_flags;

		if (!(vm->flags & (DISPLAY_FLAGS_DE_LOW |
				   DISPLAY_FLAGS_DE_HIGH))) {
			if (bus_flags & DRM_BUS_FLAG_DE_LOW)
				vm->flags |= DISPLAY_FLAGS_DE_LOW;
			else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
				vm->flags |= DISPLAY_FLAGS_DE_HIGH;
		}

		if (!(vm->flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
				   DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
			if (bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
				vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
			else if (bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
				vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
		}

		if (!(vm->flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
				   DISPLAY_FLAGS_SYNC_NEGEDGE))) {
			if (bus_flags & DRM_BUS_FLAG_SYNC_POSEDGE)
				vm->flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
			else if (bus_flags & DRM_BUS_FLAG_SYNC_NEGEDGE)
				vm->flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
		}
	}
	drm_display_mode_to_videomode(mode, &omap_crtc->vm);
}

static int omap_crtc_atomic_check(struct drm_crtc *crtc,
+42 −6
Original line number Diff line number Diff line
@@ -103,9 +103,9 @@ static int omap_encoder_update(struct drm_encoder *encoder,
	int ret;

	for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) {
		if (!dssdev->ops->check_timings)
			continue;
		unsigned long bus_flags = dssdev->bus_flags;

		if (dssdev->ops->check_timings) {
			ret = dssdev->ops->check_timings(dssdev, vm);
			if (ret) {
				dev_err(dev->dev, "invalid timings: %d\n", ret);
@@ -113,6 +113,42 @@ static int omap_encoder_update(struct drm_encoder *encoder,
			}
		}

		/*
		 * HACK: This fixes the vm flags.
		 * struct drm_display_mode does not contain the VSYNC/HSYNC/DE
		 * flags and they get lost when converting back and forth
		 * between struct drm_display_mode and struct videomode. The
		 * hack below goes and fetches the missing flags.
		 *
		 * A better solution is to use DRM's bus-flags through the whole
		 * driver.
		 */

		if (!(vm->flags & (DISPLAY_FLAGS_DE_LOW |
				   DISPLAY_FLAGS_DE_HIGH))) {
			if (bus_flags & DRM_BUS_FLAG_DE_LOW)
				vm->flags |= DISPLAY_FLAGS_DE_LOW;
			else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
				vm->flags |= DISPLAY_FLAGS_DE_HIGH;
		}

		if (!(vm->flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
				   DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
			if (bus_flags & DRM_BUS_FLAG_PIXDATA_POSEDGE)
				vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
			else if (bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
				vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
		}

		if (!(vm->flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
				   DISPLAY_FLAGS_SYNC_NEGEDGE))) {
			if (bus_flags & DRM_BUS_FLAG_SYNC_POSEDGE)
				vm->flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
			else if (bus_flags & DRM_BUS_FLAG_SYNC_NEGEDGE)
				vm->flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
		}
	}

	if (display->ops->set_timings)
		display->ops->set_timings(display, vm);