aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Etheridge <detheridge@ti.com>2013-06-21 14:52:25 -0400
committerDave Airlie <airlied@redhat.com>2013-06-27 19:12:39 -0400
commite1c5d0a819e495a79cf76a8c63c5a30c327a89a5 (patch)
treeb302ebb8e433a1824a1ff2a46f2e2413bd2a2a50
parentdb2b4bd09b43fc27ecd097e193f1135f5e40d347 (diff)
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>
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c46
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 086e52af1bc7..1d296707ceda 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)
437{ 437{
438 struct tilcdc_drm_private *priv = crtc->dev->dev_private; 438 struct tilcdc_drm_private *priv = crtc->dev->dev_private;
439 unsigned int bandwidth; 439 unsigned int bandwidth;
440 uint32_t hbp, hfp, hsw, vbp, vfp, vsw;
440 441
442 /*
443 * check to see if the width is within the range that
444 * the LCD Controller physically supports
445 */
441 if (mode->hdisplay > tilcdc_crtc_max_width(crtc)) 446 if (mode->hdisplay > tilcdc_crtc_max_width(crtc))
442 return MODE_VIRTUAL_X; 447 return MODE_VIRTUAL_X;
443 448
@@ -448,6 +453,47 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
448 if (mode->vdisplay > 2048) 453 if (mode->vdisplay > 2048)
449 return MODE_VIRTUAL_Y; 454 return MODE_VIRTUAL_Y;
450 455
456 DBG("Processing mode %dx%d@%d with pixel clock %d",
457 mode->hdisplay, mode->vdisplay,
458 drm_mode_vrefresh(mode), mode->clock);
459
460 hbp = mode->htotal - mode->hsync_end;
461 hfp = mode->hsync_start - mode->hdisplay;
462 hsw = mode->hsync_end - mode->hsync_start;
463 vbp = mode->vtotal - mode->vsync_end;
464 vfp = mode->vsync_start - mode->vdisplay;
465 vsw = mode->vsync_end - mode->vsync_start;
466
467 if ((hbp-1) & ~0x3ff) {
468 DBG("Pruning mode: Horizontal Back Porch out of range");
469 return MODE_HBLANK_WIDE;
470 }
471
472 if ((hfp-1) & ~0x3ff) {
473 DBG("Pruning mode: Horizontal Front Porch out of range");
474 return MODE_HBLANK_WIDE;
475 }
476
477 if ((hsw-1) & ~0x3ff) {
478 DBG("Pruning mode: Horizontal Sync Width out of range");
479 return MODE_HSYNC_WIDE;
480 }
481
482 if (vbp & ~0xff) {
483 DBG("Pruning mode: Vertical Back Porch out of range");
484 return MODE_VBLANK_WIDE;
485 }
486
487 if (vfp & ~0xff) {
488 DBG("Pruning mode: Vertical Front Porch out of range");
489 return MODE_VBLANK_WIDE;
490 }
491
492 if ((vsw-1) & ~0x3f) {
493 DBG("Pruning mode: Vertical Sync Width out of range");
494 return MODE_VSYNC_WIDE;
495 }
496
451 /* 497 /*
452 * some devices have a maximum allowed pixel clock 498 * some devices have a maximum allowed pixel clock
453 * configured from the DT 499 * configured from the DT