diff options
author | Darren Etheridge <detheridge@ti.com> | 2013-06-21 18:52:25 (GMT) |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-06-27 23:12:39 (GMT) |
commit | e1c5d0a819e495a79cf76a8c63c5a30c327a89a5 (patch) | |
tree | b302ebb8e433a1824a1ff2a46f2e2413bd2a2a50 /drivers/gpu/drm/tilcdc | |
parent | db2b4bd09b43fc27ecd097e193f1135f5e40d347 (diff) | |
download | linux-e1c5d0a819e495a79cf76a8c63c5a30c327a89a5.tar.xz |
drm/tilcdc: adding more guards to prevent selection of invalid modes
The tilcdc has a number of limitations for the allowed sizes of
the various adjustable timing parameter. Some modes are outside
of these timings. This commit will prune modes that report timings
that will overflow the allowed sizes in the tilcdc.
Signed-off-by: Darren Etheridge <detheridge@ti.com>
Acked-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 086e52a..1d29670 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -437,7 +437,12 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode) { struct tilcdc_drm_private *priv = crtc->dev->dev_private; unsigned int bandwidth; + uint32_t hbp, hfp, hsw, vbp, vfp, vsw; + /* + * check to see if the width is within the range that + * the LCD Controller physically supports + */ if (mode->hdisplay > tilcdc_crtc_max_width(crtc)) return MODE_VIRTUAL_X; @@ -448,6 +453,47 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode) if (mode->vdisplay > 2048) return MODE_VIRTUAL_Y; + DBG("Processing mode %dx%d@%d with pixel clock %d", + mode->hdisplay, mode->vdisplay, + drm_mode_vrefresh(mode), mode->clock); + + hbp = mode->htotal - mode->hsync_end; + hfp = mode->hsync_start - mode->hdisplay; + hsw = mode->hsync_end - mode->hsync_start; + vbp = mode->vtotal - mode->vsync_end; + vfp = mode->vsync_start - mode->vdisplay; + vsw = mode->vsync_end - mode->vsync_start; + + if ((hbp-1) & ~0x3ff) { + DBG("Pruning mode: Horizontal Back Porch out of range"); + return MODE_HBLANK_WIDE; + } + + if ((hfp-1) & ~0x3ff) { + DBG("Pruning mode: Horizontal Front Porch out of range"); + return MODE_HBLANK_WIDE; + } + + if ((hsw-1) & ~0x3ff) { + DBG("Pruning mode: Horizontal Sync Width out of range"); + return MODE_HSYNC_WIDE; + } + + if (vbp & ~0xff) { + DBG("Pruning mode: Vertical Back Porch out of range"); + return MODE_VBLANK_WIDE; + } + + if (vfp & ~0xff) { + DBG("Pruning mode: Vertical Front Porch out of range"); + return MODE_VBLANK_WIDE; + } + + if ((vsw-1) & ~0x3f) { + DBG("Pruning mode: Vertical Sync Width out of range"); + return MODE_VSYNC_WIDE; + } + /* * some devices have a maximum allowed pixel clock * configured from the DT |