aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c79
1 files changed, 66 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2b6ce9b2674a..461a637f1ef7 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
3258static void ironlake_crtc_disable(struct drm_crtc *crtc) 3268static void ironlake_crtc_disable(struct drm_crtc *crtc)
@@ -7882,6 +7892,34 @@ struct intel_quirk {
7882 void (*hook)(struct drm_device *dev); 7892 void (*hook)(struct drm_device *dev);
7883}; 7893};
7884 7894
7895/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
7896struct intel_dmi_quirk {
7897 void (*hook)(struct drm_device *dev);
7898 const struct dmi_system_id (*dmi_id_list)[];
7899};
7900
7901static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
7902{
7903 DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
7904 return 1;
7905}
7906
7907static const struct intel_dmi_quirk intel_dmi_quirks[] = {
7908 {
7909 .dmi_id_list = &(const struct dmi_system_id[]) {
7910 {
7911 .callback = intel_dmi_reverse_brightness,
7912 .ident = "NCR Corporation",
7913 .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
7914 DMI_MATCH(DMI_PRODUCT_NAME, ""),
7915 },
7916 },
7917 { } /* terminating entry */
7918 },
7919 .hook = quirk_invert_brightness,
7920 },
7921};
7922
7885static struct intel_quirk intel_quirks[] = { 7923static struct intel_quirk intel_quirks[] = {
7886 /* HP Mini needs pipe A force quirk (LP: #322104) */ 7924 /* HP Mini needs pipe A force quirk (LP: #322104) */
7887 { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, 7925 { 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
@@ -7892,8 +7930,7 @@ static struct intel_quirk intel_quirks[] = {
7892 /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ 7930 /* ThinkPad T60 needs pipe A force quirk (bug #16494) */
7893 { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, 7931 { 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
7894 7932
7895 /* 855 & before need to leave pipe A & dpll A up */ 7933 /* 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 }, 7934 { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
7898 { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, 7935 { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
7899 7936
@@ -7922,6 +7959,10 @@ static void intel_init_quirks(struct drm_device *dev)
7922 q->subsystem_device == PCI_ANY_ID)) 7959 q->subsystem_device == PCI_ANY_ID))
7923 q->hook(dev); 7960 q->hook(dev);
7924 } 7961 }
7962 for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
7963 if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
7964 intel_dmi_quirks[i].hook(dev);
7965 }
7925} 7966}
7926 7967
7927/* Disable the VGA plane that we never use */ 7968/* Disable the VGA plane that we never use */
@@ -8049,29 +8090,42 @@ static void intel_enable_pipe_a(struct drm_device *dev)
8049 8090
8050} 8091}
8051 8092
8093static bool
8094intel_check_plane_mapping(struct intel_crtc *crtc)
8095{
8096 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
8097 u32 reg, val;
8098
8099 if (dev_priv->num_pipe == 1)
8100 return true;
8101
8102 reg = DSPCNTR(!crtc->plane);
8103 val = I915_READ(reg);
8104
8105 if ((val & DISPLAY_PLANE_ENABLE) &&
8106 (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
8107 return false;
8108
8109 return true;
8110}
8111
8052static void intel_sanitize_crtc(struct intel_crtc *crtc) 8112static void intel_sanitize_crtc(struct intel_crtc *crtc)
8053{ 8113{
8054 struct drm_device *dev = crtc->base.dev; 8114 struct drm_device *dev = crtc->base.dev;
8055 struct drm_i915_private *dev_priv = dev->dev_private; 8115 struct drm_i915_private *dev_priv = dev->dev_private;
8056 u32 reg, val; 8116 u32 reg;
8057 8117
8058 /* Clear any frame start delays used for debugging left by the BIOS */ 8118 /* Clear any frame start delays used for debugging left by the BIOS */
8059 reg = PIPECONF(crtc->pipe); 8119 reg = PIPECONF(crtc->pipe);
8060 I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); 8120 I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
8061 8121
8062 /* We need to sanitize the plane -> pipe mapping first because this will 8122 /* 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. */ 8123 * disable the crtc (and hence change the state) if it is wrong. Note
8064 if (!HAS_PCH_SPLIT(dev)) { 8124 * that gen4+ has a fixed plane -> pipe mapping. */
8125 if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) {
8065 struct intel_connector *connector; 8126 struct intel_connector *connector;
8066 bool plane; 8127 bool plane;
8067 8128
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", 8129 DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n",
8076 crtc->base.base.id); 8130 crtc->base.base.id);
8077 8131
@@ -8095,7 +8149,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
8095 WARN_ON(crtc->active); 8149 WARN_ON(crtc->active);
8096 crtc->base.enabled = false; 8150 crtc->base.enabled = false;
8097 } 8151 }
8098ok:
8099 8152
8100 if (dev_priv->quirks & QUIRK_PIPEA_FORCE && 8153 if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
8101 crtc->pipe == PIPE_A && !crtc->active) { 8154 crtc->pipe == PIPE_A && !crtc->active) {