diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2b6ce9b2674a..682bd3729baf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3253,6 +3253,16 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
3253 | 3253 | ||
3254 | if (HAS_PCH_CPT(dev)) | 3254 | if (HAS_PCH_CPT(dev)) |
3255 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); | 3255 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); |
3256 | |||
3257 | /* | ||
3258 | * There seems to be a race in PCH platform hw (at least on some | ||
3259 | * outputs) where an enabled pipe still completes any pageflip right | ||
3260 | * away (as if the pipe is off) instead of waiting for vblank. As soon | ||
3261 | * as the first vblank happend, everything works as expected. Hence just | ||
3262 | * wait for one vblank before returning to avoid strange things | ||
3263 | * happening. | ||
3264 | */ | ||
3265 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
3256 | } | 3266 | } |
3257 | 3267 | ||
3258 | static void ironlake_crtc_disable(struct drm_crtc *crtc) | 3268 | static void ironlake_crtc_disable(struct drm_crtc *crtc) |
@@ -7892,8 +7902,7 @@ static struct intel_quirk intel_quirks[] = { | |||
7892 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ | 7902 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ |
7893 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, | 7903 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, |
7894 | 7904 | ||
7895 | /* 855 & before need to leave pipe A & dpll A up */ | 7905 | /* 830/845 need to leave pipe A & dpll A up */ |
7896 | { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | ||
7897 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7906 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
7898 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | 7907 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
7899 | 7908 | ||
@@ -8049,29 +8058,42 @@ static void intel_enable_pipe_a(struct drm_device *dev) | |||
8049 | 8058 | ||
8050 | } | 8059 | } |
8051 | 8060 | ||
8061 | static bool | ||
8062 | intel_check_plane_mapping(struct intel_crtc *crtc) | ||
8063 | { | ||
8064 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | ||
8065 | u32 reg, val; | ||
8066 | |||
8067 | if (dev_priv->num_pipe == 1) | ||
8068 | return true; | ||
8069 | |||
8070 | reg = DSPCNTR(!crtc->plane); | ||
8071 | val = I915_READ(reg); | ||
8072 | |||
8073 | if ((val & DISPLAY_PLANE_ENABLE) && | ||
8074 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | ||
8075 | return false; | ||
8076 | |||
8077 | return true; | ||
8078 | } | ||
8079 | |||
8052 | static void intel_sanitize_crtc(struct intel_crtc *crtc) | 8080 | static void intel_sanitize_crtc(struct intel_crtc *crtc) |
8053 | { | 8081 | { |
8054 | struct drm_device *dev = crtc->base.dev; | 8082 | struct drm_device *dev = crtc->base.dev; |
8055 | struct drm_i915_private *dev_priv = dev->dev_private; | 8083 | struct drm_i915_private *dev_priv = dev->dev_private; |
8056 | u32 reg, val; | 8084 | u32 reg; |
8057 | 8085 | ||
8058 | /* Clear any frame start delays used for debugging left by the BIOS */ | 8086 | /* Clear any frame start delays used for debugging left by the BIOS */ |
8059 | reg = PIPECONF(crtc->pipe); | 8087 | reg = PIPECONF(crtc->pipe); |
8060 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); | 8088 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); |
8061 | 8089 | ||
8062 | /* We need to sanitize the plane -> pipe mapping first because this will | 8090 | /* We need to sanitize the plane -> pipe mapping first because this will |
8063 | * disable the crtc (and hence change the state) if it is wrong. */ | 8091 | * disable the crtc (and hence change the state) if it is wrong. Note |
8064 | if (!HAS_PCH_SPLIT(dev)) { | 8092 | * that gen4+ has a fixed plane -> pipe mapping. */ |
8093 | if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) { | ||
8065 | struct intel_connector *connector; | 8094 | struct intel_connector *connector; |
8066 | bool plane; | 8095 | bool plane; |
8067 | 8096 | ||
8068 | reg = DSPCNTR(crtc->plane); | ||
8069 | val = I915_READ(reg); | ||
8070 | |||
8071 | if ((val & DISPLAY_PLANE_ENABLE) == 0 && | ||
8072 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | ||
8073 | goto ok; | ||
8074 | |||
8075 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", | 8097 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", |
8076 | crtc->base.base.id); | 8098 | crtc->base.base.id); |
8077 | 8099 | ||
@@ -8095,7 +8117,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) | |||
8095 | WARN_ON(crtc->active); | 8117 | WARN_ON(crtc->active); |
8096 | crtc->base.enabled = false; | 8118 | crtc->base.enabled = false; |
8097 | } | 8119 | } |
8098 | ok: | ||
8099 | 8120 | ||
8100 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && | 8121 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && |
8101 | crtc->pipe == PIPE_A && !crtc->active) { | 8122 | crtc->pipe == PIPE_A && !crtc->active) { |