diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-06-07 17:32:16 +0200 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2018-09-03 15:13:30 +0200 |
commit | 8e9c1c6676ea3d0dc60d84ee9a69984a4bcf859f (patch) | |
tree | e549035e06fbd176d9a9b39556fab7d4ec34802f /drivers/gpu/drm/omapdrm/omap_encoder.c | |
parent | drm/omap: panels: Don't modify fixed timings (diff) | |
download | linux-8e9c1c6676ea3d0dc60d84ee9a69984a4bcf859f.tar.xz linux-8e9c1c6676ea3d0dc60d84ee9a69984a4bcf859f.zip |
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; } } |