diff options
| author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-06-07 18:32:16 +0300 | 
|---|---|---|
| committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2018-09-03 16:13:30 +0300 | 
| commit | 8e9c1c6676ea3d0dc60d84ee9a69984a4bcf859f (patch) | |
| tree | e549035e06fbd176d9a9b39556fab7d4ec34802f /drivers/gpu/drm/omapdrm/omap_encoder.c | |
| parent | 31cd7afa3086f1206ef4c7434e033669702adf08 (diff) | |
| download | linux-8e9c1c6676ea3d0dc60d84ee9a69984a4bcf859f.tar.xz | |
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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_encoder.c')
| -rw-r--r-- | drivers/gpu/drm/omapdrm/omap_encoder.c | 48 | 
1 files changed, 42 insertions, 6 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index bb010c20d8b8..82cdcba961a8 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -103,13 +103,49 @@ 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); +				return ret; +			} +		} + +		/* +		 * 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; +		} -		ret = dssdev->ops->check_timings(dssdev, vm); -		if (ret) { -			dev_err(dev->dev, "invalid timings: %d\n", ret); -			return ret; +		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;  		}  	}  | 
