aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-08-14 18:22:07 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-09-03 05:05:24 -0400
commitb6b5d049780c29fe6073b6ecbb712dd8dcb27ebc (patch)
tree430498f78d9abd507fece663c195094003a0ace3 /drivers/gpu
parent5f080c0f4bd526b36361dd15c4d22f6bbad95af9 (diff)
drm/i915: Add pipe B force quirk for 830M
830M has problems when some of the pipes are disabled. Namely if a plane, DVO port etc. is currently assigned to a disabled pipe, it can't moved to the other pipe until the current pipe is also enabled. To keep things simple just leave both pipes running all the time. Ideally I think should turn the pipes off if neither is active, and when either becomes active we enable both. But that would reuquire proper atomic modeset support, and probably a bit of extra care in the order things get enabled. v2: Reorder wrt. double wide handling changes Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Tested-by: Thomas Richter <richter@rus.uni-stuttgart.de> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_display.c39
2 files changed, 28 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 13db41833f3d..dbf9a26d1a89 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -709,6 +709,7 @@ enum intel_sbi_destination {
709#define QUIRK_LVDS_SSC_DISABLE (1<<1) 709#define QUIRK_LVDS_SSC_DISABLE (1<<1)
710#define QUIRK_INVERT_BRIGHTNESS (1<<2) 710#define QUIRK_INVERT_BRIGHTNESS (1<<2)
711#define QUIRK_BACKLIGHT_PRESENT (1<<3) 711#define QUIRK_BACKLIGHT_PRESENT (1<<3)
712#define QUIRK_PIPEB_FORCE (1<<4)
712 713
713struct intel_fbdev; 714struct intel_fbdev;
714struct intel_fbc_work; 715struct intel_fbc_work;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c06b516c1359..7e20b00d56a3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1261,8 +1261,9 @@ void assert_pipe(struct drm_i915_private *dev_priv,
1261 enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, 1261 enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
1262 pipe); 1262 pipe);
1263 1263
1264 /* if we need the pipe A quirk it must be always on */ 1264 /* if we need the pipe quirk it must be always on */
1265 if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) 1265 if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
1266 (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
1266 state = true; 1267 state = true;
1267 1268
1268 if (!intel_display_power_enabled(dev_priv, 1269 if (!intel_display_power_enabled(dev_priv,
@@ -1662,8 +1663,9 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
1662 */ 1663 */
1663static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) 1664static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
1664{ 1665{
1665 /* Don't disable pipe A or pipe A PLLs if needed */ 1666 /* Don't disable pipe or pipe PLLs if needed */
1666 if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) 1667 if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
1668 (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
1667 return; 1669 return;
1668 1670
1669 /* Make sure the pipe isn't still relying on us */ 1671 /* Make sure the pipe isn't still relying on us */
@@ -2031,8 +2033,8 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
2031 reg = PIPECONF(cpu_transcoder); 2033 reg = PIPECONF(cpu_transcoder);
2032 val = I915_READ(reg); 2034 val = I915_READ(reg);
2033 if (val & PIPECONF_ENABLE) { 2035 if (val & PIPECONF_ENABLE) {
2034 WARN_ON(!(pipe == PIPE_A && 2036 WARN_ON(!((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
2035 dev_priv->quirks & QUIRK_PIPEA_FORCE)); 2037 (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)));
2036 return; 2038 return;
2037 } 2039 }
2038 2040
@@ -2079,7 +2081,8 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
2079 val &= ~PIPECONF_DOUBLE_WIDE; 2081 val &= ~PIPECONF_DOUBLE_WIDE;
2080 2082
2081 /* Don't disable pipe or pipe PLLs if needed */ 2083 /* Don't disable pipe or pipe PLLs if needed */
2082 if (!(pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)) 2084 if (!(pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) &&
2085 !(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
2083 val &= ~PIPECONF_ENABLE; 2086 val &= ~PIPECONF_ENABLE;
2084 2087
2085 I915_WRITE(reg, val); 2088 I915_WRITE(reg, val);
@@ -6039,9 +6042,9 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
6039 6042
6040 pipeconf = 0; 6043 pipeconf = 0;
6041 6044
6042 if (dev_priv->quirks & QUIRK_PIPEA_FORCE && 6045 if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
6043 I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE) 6046 (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
6044 pipeconf |= PIPECONF_ENABLE; 6047 pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE;
6045 6048
6046 if (intel_crtc->config.double_wide) 6049 if (intel_crtc->config.double_wide)
6047 pipeconf |= PIPECONF_DOUBLE_WIDE; 6050 pipeconf |= PIPECONF_DOUBLE_WIDE;
@@ -10754,8 +10757,9 @@ check_crtc_state(struct drm_device *dev)
10754 active = dev_priv->display.get_pipe_config(crtc, 10757 active = dev_priv->display.get_pipe_config(crtc,
10755 &pipe_config); 10758 &pipe_config);
10756 10759
10757 /* hw state is inconsistent with the pipe A quirk */ 10760 /* hw state is inconsistent with the pipe quirk */
10758 if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) 10761 if ((crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
10762 (crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
10759 active = crtc->active; 10763 active = crtc->active;
10760 10764
10761 for_each_intel_encoder(dev, encoder) { 10765 for_each_intel_encoder(dev, encoder) {
@@ -12565,6 +12569,14 @@ static void quirk_pipea_force(struct drm_device *dev)
12565 DRM_INFO("applying pipe a force quirk\n"); 12569 DRM_INFO("applying pipe a force quirk\n");
12566} 12570}
12567 12571
12572static void quirk_pipeb_force(struct drm_device *dev)
12573{
12574 struct drm_i915_private *dev_priv = dev->dev_private;
12575
12576 dev_priv->quirks |= QUIRK_PIPEB_FORCE;
12577 DRM_INFO("applying pipe b force quirk\n");
12578}
12579
12568/* 12580/*
12569 * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason 12581 * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
12570 */ 12582 */
@@ -12642,6 +12654,9 @@ static struct intel_quirk intel_quirks[] = {
12642 /* 830 needs to leave pipe A & dpll A up */ 12654 /* 830 needs to leave pipe A & dpll A up */
12643 { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, 12655 { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
12644 12656
12657 /* 830 needs to leave pipe B & dpll B up */
12658 { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipeb_force },
12659
12645 /* Lenovo U160 cannot use SSC on LVDS */ 12660 /* Lenovo U160 cannot use SSC on LVDS */
12646 { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, 12661 { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
12647 12662