diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-06-15 20:44:05 +0300 |
---|---|---|
committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2018-06-19 17:18:24 +0300 |
commit | ad77c537eab1c28732e02c03f3da82917722bef6 (patch) | |
tree | 9a9c8965f94d7c4ff948caa2f79f21d1bfd207b6 | |
parent | 98fac1d5c5825e61721c7b73875f8b46159e6dcb (diff) | |
download | linux-ad77c537eab1c28732e02c03f3da82917722bef6.tar.xz |
drm/i915: Check timings against hardware maximums
Validate that all display timings fit within the number of bits
we have in the transcoder timing registers.
The limits are:
hsw+:
4k: vdisplay, vblank_start
8k: everything else
gen3+:
4k: h/vdisplay, h/vblank_start
8k: everything else
gen2:
2k: h/vdisplay, h/vblank_start
4k: everything else
Also document the fact that the mode_config.max_width/height limits
refer to just the max framebuffer dimensions we support. Which may
be larger than the max hdisplay/vdisplay.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180615174406.12258-2-ville.syrjala@linux.intel.com
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index aa7fed31ccda..b2a5a9ed9404 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14570,6 +14570,10 @@ static enum drm_mode_status intel_mode_valid(struct drm_device *dev, const struct drm_display_mode *mode) { + struct drm_i915_private *dev_priv = to_i915(dev); + int hdisplay_max, htotal_max; + int vdisplay_max, vtotal_max; + /* * Can't reject DBLSCAN here because Xorg ddxen can add piles * of DBLSCAN modes to the output's mode list when they detect @@ -14599,6 +14603,36 @@ intel_mode_valid(struct drm_device *dev, DRM_MODE_FLAG_CLKDIV2)) return MODE_BAD; + if (INTEL_GEN(dev_priv) >= 9 || + IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { + hdisplay_max = 8192; /* FDI max 4096 handled elsewhere */ + vdisplay_max = 4096; + htotal_max = 8192; + vtotal_max = 8192; + } else if (INTEL_GEN(dev_priv) >= 3) { + hdisplay_max = 4096; + vdisplay_max = 4096; + htotal_max = 8192; + vtotal_max = 8192; + } else { + hdisplay_max = 2048; + vdisplay_max = 2048; + htotal_max = 4096; + vtotal_max = 4096; + } + + if (mode->hdisplay > hdisplay_max || + mode->hsync_start > htotal_max || + mode->hsync_end > htotal_max || + mode->htotal > htotal_max) + return MODE_H_ILLEGAL; + + if (mode->vdisplay > vdisplay_max || + mode->vsync_start > vtotal_max || + mode->vsync_end > vtotal_max || + mode->vtotal > vtotal_max) + return MODE_V_ILLEGAL; + return MODE_OK; } @@ -15037,6 +15071,7 @@ int intel_modeset_init(struct drm_device *dev) } } + /* maximum framebuffer dimensions */ if (IS_GEN2(dev_priv)) { dev->mode_config.max_width = 2048; dev->mode_config.max_height = 2048; |