diff options
author | Keith Packard <keithp@keithp.com> | 2011-08-06 13:35:34 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-08-08 16:37:11 -0400 |
commit | 1519b9956eb4b4180fa3f47c73341463cdcfaa37 (patch) | |
tree | 2aaf59c10b69bb00113bb677916d3106c5ed625b /drivers/gpu | |
parent | ed10fca9c351c83ab89a97f3515089e0d36bdccc (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.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 60 |
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 | ||
1001 | static 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 | |||
1017 | static 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 | |||
1033 | static 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 | |||
1001 | static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, | 1048 | static 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); |