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) { |
