aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2011-08-06 13:35:34 -0400
committerKeith Packard <keithp@keithp.com>2011-08-08 16:37:11 -0400
commit1519b9956eb4b4180fa3f47c73341463cdcfaa37 (patch)
tree2aaf59c10b69bb00113bb677916d3106c5ed625b /drivers/gpu
parented10fca9c351c83ab89a97f3515089e0d36bdccc (diff)
drm/i915: Fix PCH port pipe select in CPT disable paths
CPT pipe select is different from previous generations (using two bits instead of one). All of the paths from intel_disable_pch_ports were not making this distinction. Mode setting with pipe A turned off would then also force all outputs on pipe B to get turned off as the disable code would mistakenly decide that all of these outputs were on pipe A and turn them off. This is an extension of the CPT DP disable fix (why didn't I fix this then?) Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h13
-rw-r--r--drivers/gpu/drm/i915/intel_display.c60
2 files changed, 58 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d1331f771e2f..5baaef4a0c5d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1318,6 +1318,7 @@
1318#define ADPA_PIPE_SELECT_MASK (1<<30) 1318#define ADPA_PIPE_SELECT_MASK (1<<30)
1319#define ADPA_PIPE_A_SELECT 0 1319#define ADPA_PIPE_A_SELECT 0
1320#define ADPA_PIPE_B_SELECT (1<<30) 1320#define ADPA_PIPE_B_SELECT (1<<30)
1321#define ADPA_PIPE_SELECT(pipe) ((pipe) << 30)
1321#define ADPA_USE_VGA_HVPOLARITY (1<<15) 1322#define ADPA_USE_VGA_HVPOLARITY (1<<15)
1322#define ADPA_SETS_HVPOLARITY 0 1323#define ADPA_SETS_HVPOLARITY 0
1323#define ADPA_VSYNC_CNTL_DISABLE (1<<11) 1324#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
@@ -1460,6 +1461,7 @@
1460/* Selects pipe B for LVDS data. Must be set on pre-965. */ 1461/* Selects pipe B for LVDS data. Must be set on pre-965. */
1461#define LVDS_PIPEB_SELECT (1 << 30) 1462#define LVDS_PIPEB_SELECT (1 << 30)
1462#define LVDS_PIPE_MASK (1 << 30) 1463#define LVDS_PIPE_MASK (1 << 30)
1464#define LVDS_PIPE(pipe) ((pipe) << 30)
1463/* LVDS dithering flag on 965/g4x platform */ 1465/* LVDS dithering flag on 965/g4x platform */
1464#define LVDS_ENABLE_DITHER (1 << 25) 1466#define LVDS_ENABLE_DITHER (1 << 25)
1465/* LVDS sync polarity flags. Set to invert (i.e. negative) */ 1467/* LVDS sync polarity flags. Set to invert (i.e. negative) */
@@ -1499,9 +1501,6 @@
1499#define LVDS_B0B3_POWER_DOWN (0 << 2) 1501#define LVDS_B0B3_POWER_DOWN (0 << 2)
1500#define LVDS_B0B3_POWER_UP (3 << 2) 1502#define LVDS_B0B3_POWER_UP (3 << 2)
1501 1503
1502#define LVDS_PIPE_ENABLED(V, P) \
1503 (((V) & (LVDS_PIPE_MASK | LVDS_PORT_EN)) == ((P) << 30 | LVDS_PORT_EN))
1504
1505/* Video Data Island Packet control */ 1504/* Video Data Island Packet control */
1506#define VIDEO_DIP_DATA 0x61178 1505#define VIDEO_DIP_DATA 0x61178
1507#define VIDEO_DIP_CTL 0x61170 1506#define VIDEO_DIP_CTL 0x61170
@@ -3256,14 +3255,12 @@
3256#define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17) 3255#define ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17)
3257#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) 3256#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
3258 3257
3259#define ADPA_PIPE_ENABLED(V, P) \
3260 (((V) & (ADPA_TRANS_SELECT_MASK | ADPA_DAC_ENABLE)) == ((P) << 30 | ADPA_DAC_ENABLE))
3261
3262/* or SDVOB */ 3258/* or SDVOB */
3263#define HDMIB 0xe1140 3259#define HDMIB 0xe1140
3264#define PORT_ENABLE (1 << 31) 3260#define PORT_ENABLE (1 << 31)
3265#define TRANSCODER_A (0) 3261#define TRANSCODER_A (0)
3266#define TRANSCODER_B (1 << 30) 3262#define TRANSCODER_B (1 << 30)
3263#define TRANSCODER(pipe) ((pipe) << 30)
3267#define TRANSCODER_MASK (1 << 30) 3264#define TRANSCODER_MASK (1 << 30)
3268#define COLOR_FORMAT_8bpc (0) 3265#define COLOR_FORMAT_8bpc (0)
3269#define COLOR_FORMAT_12bpc (3 << 26) 3266#define COLOR_FORMAT_12bpc (3 << 26)
@@ -3280,9 +3277,6 @@
3280#define HSYNC_ACTIVE_HIGH (1 << 3) 3277#define HSYNC_ACTIVE_HIGH (1 << 3)
3281#define PORT_DETECTED (1 << 2) 3278#define PORT_DETECTED (1 << 2)
3282 3279
3283#define HDMI_PIPE_ENABLED(V, P) \
3284 (((V) & (TRANSCODER_MASK | PORT_ENABLE)) == ((P) << 30 | PORT_ENABLE))
3285
3286/* PCH SDVOB multiplex with HDMIB */ 3280/* PCH SDVOB multiplex with HDMIB */
3287#define PCH_SDVOB HDMIB 3281#define PCH_SDVOB HDMIB
3288 3282
@@ -3349,6 +3343,7 @@
3349#define PORT_TRANS_B_SEL_CPT (1<<29) 3343#define PORT_TRANS_B_SEL_CPT (1<<29)
3350#define PORT_TRANS_C_SEL_CPT (2<<29) 3344#define PORT_TRANS_C_SEL_CPT (2<<29)
3351#define PORT_TRANS_SEL_MASK (3<<29) 3345#define PORT_TRANS_SEL_MASK (3<<29)
3346#define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29)
3352 3347
3353#define TRANS_DP_CTL_A 0xe0300 3348#define TRANS_DP_CTL_A 0xe0300
3354#define TRANS_DP_CTL_B 0xe1300 3349#define TRANS_DP_CTL_B 0xe1300
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 35364e68a091..4c4c903e95ab 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -998,6 +998,53 @@ static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe,
998 return true; 998 return true;
999} 999}
1000 1000
1001static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv,
1002 enum pipe pipe, u32 val)
1003{
1004 if ((val & PORT_ENABLE) == 0)
1005 return false;
1006
1007 if (HAS_PCH_CPT(dev_priv->dev)) {
1008 if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
1009 return false;
1010 } else {
1011 if ((val & TRANSCODER_MASK) != TRANSCODER(pipe))
1012 return false;
1013 }
1014 return true;
1015}
1016
1017static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv,
1018 enum pipe pipe, u32 val)
1019{
1020 if ((val & LVDS_PORT_EN) == 0)
1021 return false;
1022
1023 if (HAS_PCH_CPT(dev_priv->dev)) {
1024 if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
1025 return false;
1026 } else {
1027 if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe))
1028 return false;
1029 }
1030 return true;
1031}
1032
1033static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv,
1034 enum pipe pipe, u32 val)
1035{
1036 if ((val & ADPA_DAC_ENABLE) == 0)
1037 return false;
1038 if (HAS_PCH_CPT(dev_priv->dev)) {
1039 if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe))
1040 return false;
1041 } else {
1042 if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe))
1043 return false;
1044 }
1045 return true;
1046}
1047
1001static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, 1048static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
1002 enum pipe pipe, int reg, u32 port_sel) 1049 enum pipe pipe, int reg, u32 port_sel)
1003{ 1050{
@@ -1011,7 +1058,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
1011 enum pipe pipe, int reg) 1058 enum pipe pipe, int reg)
1012{ 1059{
1013 u32 val = I915_READ(reg); 1060 u32 val = I915_READ(reg);
1014 WARN(HDMI_PIPE_ENABLED(val, pipe), 1061 WARN(hdmi_pipe_enabled(dev_priv, val, pipe),
1015 "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", 1062 "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
1016 reg, pipe_name(pipe)); 1063 reg, pipe_name(pipe));
1017} 1064}
@@ -1028,13 +1075,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
1028 1075
1029 reg = PCH_ADPA; 1076 reg = PCH_ADPA;
1030 val = I915_READ(reg); 1077 val = I915_READ(reg);
1031 WARN(ADPA_PIPE_ENABLED(val, pipe), 1078 WARN(adpa_pipe_enabled(dev_priv, val, pipe),
1032 "PCH VGA enabled on transcoder %c, should be disabled\n", 1079 "PCH VGA enabled on transcoder %c, should be disabled\n",
1033 pipe_name(pipe)); 1080 pipe_name(pipe));
1034 1081
1035 reg = PCH_LVDS; 1082 reg = PCH_LVDS;
1036 val = I915_READ(reg); 1083 val = I915_READ(reg);
1037 WARN(LVDS_PIPE_ENABLED(val, pipe), 1084 WARN(lvds_pipe_enabled(dev_priv, val, pipe),
1038 "PCH LVDS enabled on transcoder %c, should be disabled\n", 1085 "PCH LVDS enabled on transcoder %c, should be disabled\n",
1039 pipe_name(pipe)); 1086 pipe_name(pipe));
1040 1087
@@ -1370,7 +1417,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
1370 enum pipe pipe, int reg) 1417 enum pipe pipe, int reg)
1371{ 1418{
1372 u32 val = I915_READ(reg); 1419 u32 val = I915_READ(reg);
1373 if (HDMI_PIPE_ENABLED(val, pipe)) { 1420 if (hdmi_pipe_enabled(dev_priv, val, pipe)) {
1374 DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", 1421 DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",
1375 reg, pipe); 1422 reg, pipe);
1376 I915_WRITE(reg, val & ~PORT_ENABLE); 1423 I915_WRITE(reg, val & ~PORT_ENABLE);
@@ -1392,12 +1439,13 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
1392 1439
1393 reg = PCH_ADPA; 1440 reg = PCH_ADPA;
1394 val = I915_READ(reg); 1441 val = I915_READ(reg);
1395 if (ADPA_PIPE_ENABLED(val, pipe)) 1442 if (adpa_pipe_enabled(dev_priv, val, pipe))
1396 I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); 1443 I915_WRITE(reg, val & ~ADPA_DAC_ENABLE);
1397 1444
1398 reg = PCH_LVDS; 1445 reg = PCH_LVDS;
1399 val = I915_READ(reg); 1446 val = I915_READ(reg);
1400 if (LVDS_PIPE_ENABLED(val, pipe)) { 1447 if (lvds_pipe_enabled(dev_priv, val, pipe)) {
1448 DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val);
1401 I915_WRITE(reg, val & ~LVDS_PORT_EN); 1449 I915_WRITE(reg, val & ~LVDS_PORT_EN);
1402 POSTING_READ(reg); 1450 POSTING_READ(reg);
1403 udelay(100); 1451 udelay(100);