diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2013-03-28 12:55:41 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-04-02 14:54:31 -0400 |
commit | 453c542059cfa1988cabcf84f715307cd9789163 (patch) | |
tree | 5d6019f071131d1e4f8e7953e62918f4127c622f /drivers/gpu/drm/i915/intel_dp.c | |
parent | b2634017b2df5e45567811b5e82eb0c8ce8e5ebd (diff) |
drm/i915: panel power sequencing for VLV eDP v2
PPS register offsets have changed in Valleyview.
v2: don't clobber port select bits on VLV when fixing up PPS timings
don't bother with G4x PPS regs (Jani)
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com>
Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com>
Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 173 |
1 files changed, 122 insertions, 51 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index eb783925b28c..64c8d3ed8d0f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -274,16 +274,20 @@ static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp) | |||
274 | { | 274 | { |
275 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 275 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
276 | struct drm_i915_private *dev_priv = dev->dev_private; | 276 | struct drm_i915_private *dev_priv = dev->dev_private; |
277 | u32 pp_stat_reg; | ||
277 | 278 | ||
278 | return (I915_READ(PCH_PP_STATUS) & PP_ON) != 0; | 279 | pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; |
280 | return (I915_READ(pp_stat_reg) & PP_ON) != 0; | ||
279 | } | 281 | } |
280 | 282 | ||
281 | static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp) | 283 | static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp) |
282 | { | 284 | { |
283 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 285 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
284 | struct drm_i915_private *dev_priv = dev->dev_private; | 286 | struct drm_i915_private *dev_priv = dev->dev_private; |
287 | u32 pp_ctrl_reg; | ||
285 | 288 | ||
286 | return (I915_READ(PCH_PP_CONTROL) & EDP_FORCE_VDD) != 0; | 289 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; |
290 | return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0; | ||
287 | } | 291 | } |
288 | 292 | ||
289 | static void | 293 | static void |
@@ -291,14 +295,19 @@ intel_dp_check_edp(struct intel_dp *intel_dp) | |||
291 | { | 295 | { |
292 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 296 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
293 | struct drm_i915_private *dev_priv = dev->dev_private; | 297 | struct drm_i915_private *dev_priv = dev->dev_private; |
298 | u32 pp_stat_reg, pp_ctrl_reg; | ||
294 | 299 | ||
295 | if (!is_edp(intel_dp)) | 300 | if (!is_edp(intel_dp)) |
296 | return; | 301 | return; |
302 | |||
303 | pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; | ||
304 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; | ||
305 | |||
297 | if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) { | 306 | if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) { |
298 | WARN(1, "eDP powered off while attempting aux channel communication.\n"); | 307 | WARN(1, "eDP powered off while attempting aux channel communication.\n"); |
299 | DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n", | 308 | DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n", |
300 | I915_READ(PCH_PP_STATUS), | 309 | I915_READ(pp_stat_reg), |
301 | I915_READ(PCH_PP_CONTROL)); | 310 | I915_READ(pp_ctrl_reg)); |
302 | } | 311 | } |
303 | } | 312 | } |
304 | 313 | ||
@@ -981,16 +990,20 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp, | |||
981 | { | 990 | { |
982 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 991 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
983 | struct drm_i915_private *dev_priv = dev->dev_private; | 992 | struct drm_i915_private *dev_priv = dev->dev_private; |
993 | u32 pp_stat_reg, pp_ctrl_reg; | ||
994 | |||
995 | pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; | ||
996 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; | ||
984 | 997 | ||
985 | DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", | 998 | DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", |
986 | mask, value, | 999 | mask, value, |
987 | I915_READ(PCH_PP_STATUS), | 1000 | I915_READ(pp_stat_reg), |
988 | I915_READ(PCH_PP_CONTROL)); | 1001 | I915_READ(pp_ctrl_reg)); |
989 | 1002 | ||
990 | if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) { | 1003 | if (_wait_for((I915_READ(pp_stat_reg) & mask) == value, 5000, 10)) { |
991 | DRM_ERROR("Panel status timeout: status %08x control %08x\n", | 1004 | DRM_ERROR("Panel status timeout: status %08x control %08x\n", |
992 | I915_READ(PCH_PP_STATUS), | 1005 | I915_READ(pp_stat_reg), |
993 | I915_READ(PCH_PP_CONTROL)); | 1006 | I915_READ(pp_ctrl_reg)); |
994 | } | 1007 | } |
995 | } | 1008 | } |
996 | 1009 | ||
@@ -1017,9 +1030,15 @@ static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp) | |||
1017 | * is locked | 1030 | * is locked |
1018 | */ | 1031 | */ |
1019 | 1032 | ||
1020 | static u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv) | 1033 | static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) |
1021 | { | 1034 | { |
1022 | u32 control = I915_READ(PCH_PP_CONTROL); | 1035 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1036 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1037 | u32 control; | ||
1038 | u32 pp_ctrl_reg; | ||
1039 | |||
1040 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; | ||
1041 | control = I915_READ(pp_ctrl_reg); | ||
1023 | 1042 | ||
1024 | control &= ~PANEL_UNLOCK_MASK; | 1043 | control &= ~PANEL_UNLOCK_MASK; |
1025 | control |= PANEL_UNLOCK_REGS; | 1044 | control |= PANEL_UNLOCK_REGS; |
@@ -1031,6 +1050,7 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) | |||
1031 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1050 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1032 | struct drm_i915_private *dev_priv = dev->dev_private; | 1051 | struct drm_i915_private *dev_priv = dev->dev_private; |
1033 | u32 pp; | 1052 | u32 pp; |
1053 | u32 pp_stat_reg, pp_ctrl_reg; | ||
1034 | 1054 | ||
1035 | if (!is_edp(intel_dp)) | 1055 | if (!is_edp(intel_dp)) |
1036 | return; | 1056 | return; |
@@ -1049,13 +1069,16 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) | |||
1049 | if (!ironlake_edp_have_panel_power(intel_dp)) | 1069 | if (!ironlake_edp_have_panel_power(intel_dp)) |
1050 | ironlake_wait_panel_power_cycle(intel_dp); | 1070 | ironlake_wait_panel_power_cycle(intel_dp); |
1051 | 1071 | ||
1052 | pp = ironlake_get_pp_control(dev_priv); | 1072 | pp = ironlake_get_pp_control(intel_dp); |
1053 | pp |= EDP_FORCE_VDD; | 1073 | pp |= EDP_FORCE_VDD; |
1054 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1055 | POSTING_READ(PCH_PP_CONTROL); | ||
1056 | DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", | ||
1057 | I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); | ||
1058 | 1074 | ||
1075 | pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; | ||
1076 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; | ||
1077 | |||
1078 | I915_WRITE(pp_ctrl_reg, pp); | ||
1079 | POSTING_READ(pp_ctrl_reg); | ||
1080 | DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n", | ||
1081 | I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg)); | ||
1059 | /* | 1082 | /* |
1060 | * If the panel wasn't on, delay before accessing aux channel | 1083 | * If the panel wasn't on, delay before accessing aux channel |
1061 | */ | 1084 | */ |
@@ -1070,19 +1093,23 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) | |||
1070 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1093 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1071 | struct drm_i915_private *dev_priv = dev->dev_private; | 1094 | struct drm_i915_private *dev_priv = dev->dev_private; |
1072 | u32 pp; | 1095 | u32 pp; |
1096 | u32 pp_stat_reg, pp_ctrl_reg; | ||
1073 | 1097 | ||
1074 | WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); | 1098 | WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); |
1075 | 1099 | ||
1076 | if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { | 1100 | if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { |
1077 | pp = ironlake_get_pp_control(dev_priv); | 1101 | pp = ironlake_get_pp_control(intel_dp); |
1078 | pp &= ~EDP_FORCE_VDD; | 1102 | pp &= ~EDP_FORCE_VDD; |
1079 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
1080 | POSTING_READ(PCH_PP_CONTROL); | ||
1081 | 1103 | ||
1082 | /* Make sure sequencer is idle before allowing subsequent activity */ | 1104 | pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; |
1083 | DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", | 1105 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; |
1084 | I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); | 1106 | |
1107 | I915_WRITE(pp_ctrl_reg, pp); | ||
1108 | POSTING_READ(pp_ctrl_reg); | ||
1085 | 1109 | ||
1110 | /* Make sure sequencer is idle before allowing subsequent activity */ | ||
1111 | DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n", | ||
1112 | I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg)); | ||
1086 | msleep(intel_dp->panel_power_down_delay); | 1113 | msleep(intel_dp->panel_power_down_delay); |
1087 | } | 1114 | } |
1088 | } | 1115 | } |
@@ -1126,6 +1153,7 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp) | |||
1126 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1153 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1127 | struct drm_i915_private *dev_priv = dev->dev_private; | 1154 | struct drm_i915_private *dev_priv = dev->dev_private; |
1128 | u32 pp; | 1155 | u32 pp; |
1156 | u32 pp_ctrl_reg; | ||
1129 | 1157 | ||
1130 | if (!is_edp(intel_dp)) | 1158 | if (!is_edp(intel_dp)) |
1131 | return; | 1159 | return; |
@@ -1139,7 +1167,7 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp) | |||
1139 | 1167 | ||
1140 | ironlake_wait_panel_power_cycle(intel_dp); | 1168 | ironlake_wait_panel_power_cycle(intel_dp); |
1141 | 1169 | ||
1142 | pp = ironlake_get_pp_control(dev_priv); | 1170 | pp = ironlake_get_pp_control(intel_dp); |
1143 | if (IS_GEN5(dev)) { | 1171 | if (IS_GEN5(dev)) { |
1144 | /* ILK workaround: disable reset around power sequence */ | 1172 | /* ILK workaround: disable reset around power sequence */ |
1145 | pp &= ~PANEL_POWER_RESET; | 1173 | pp &= ~PANEL_POWER_RESET; |
@@ -1151,8 +1179,10 @@ void ironlake_edp_panel_on(struct intel_dp *intel_dp) | |||
1151 | if (!IS_GEN5(dev)) | 1179 | if (!IS_GEN5(dev)) |
1152 | pp |= PANEL_POWER_RESET; | 1180 | pp |= PANEL_POWER_RESET; |
1153 | 1181 | ||
1154 | I915_WRITE(PCH_PP_CONTROL, pp); | 1182 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; |
1155 | POSTING_READ(PCH_PP_CONTROL); | 1183 | |
1184 | I915_WRITE(pp_ctrl_reg, pp); | ||
1185 | POSTING_READ(pp_ctrl_reg); | ||
1156 | 1186 | ||
1157 | ironlake_wait_panel_on(intel_dp); | 1187 | ironlake_wait_panel_on(intel_dp); |
1158 | 1188 | ||
@@ -1168,6 +1198,7 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
1168 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1198 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1169 | struct drm_i915_private *dev_priv = dev->dev_private; | 1199 | struct drm_i915_private *dev_priv = dev->dev_private; |
1170 | u32 pp; | 1200 | u32 pp; |
1201 | u32 pp_ctrl_reg; | ||
1171 | 1202 | ||
1172 | if (!is_edp(intel_dp)) | 1203 | if (!is_edp(intel_dp)) |
1173 | return; | 1204 | return; |
@@ -1176,12 +1207,15 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
1176 | 1207 | ||
1177 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); | 1208 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); |
1178 | 1209 | ||
1179 | pp = ironlake_get_pp_control(dev_priv); | 1210 | pp = ironlake_get_pp_control(intel_dp); |
1180 | /* We need to switch off panel power _and_ force vdd, for otherwise some | 1211 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
1181 | * panels get very unhappy and cease to work. */ | 1212 | * panels get very unhappy and cease to work. */ |
1182 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1213 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); |
1183 | I915_WRITE(PCH_PP_CONTROL, pp); | 1214 | |
1184 | POSTING_READ(PCH_PP_CONTROL); | 1215 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; |
1216 | |||
1217 | I915_WRITE(pp_ctrl_reg, pp); | ||
1218 | POSTING_READ(pp_ctrl_reg); | ||
1185 | 1219 | ||
1186 | intel_dp->want_panel_vdd = false; | 1220 | intel_dp->want_panel_vdd = false; |
1187 | 1221 | ||
@@ -1195,6 +1229,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | |||
1195 | struct drm_i915_private *dev_priv = dev->dev_private; | 1229 | struct drm_i915_private *dev_priv = dev->dev_private; |
1196 | int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe; | 1230 | int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe; |
1197 | u32 pp; | 1231 | u32 pp; |
1232 | u32 pp_ctrl_reg; | ||
1198 | 1233 | ||
1199 | if (!is_edp(intel_dp)) | 1234 | if (!is_edp(intel_dp)) |
1200 | return; | 1235 | return; |
@@ -1207,10 +1242,13 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | |||
1207 | * allowing it to appear. | 1242 | * allowing it to appear. |
1208 | */ | 1243 | */ |
1209 | msleep(intel_dp->backlight_on_delay); | 1244 | msleep(intel_dp->backlight_on_delay); |
1210 | pp = ironlake_get_pp_control(dev_priv); | 1245 | pp = ironlake_get_pp_control(intel_dp); |
1211 | pp |= EDP_BLC_ENABLE; | 1246 | pp |= EDP_BLC_ENABLE; |
1212 | I915_WRITE(PCH_PP_CONTROL, pp); | 1247 | |
1213 | POSTING_READ(PCH_PP_CONTROL); | 1248 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; |
1249 | |||
1250 | I915_WRITE(pp_ctrl_reg, pp); | ||
1251 | POSTING_READ(pp_ctrl_reg); | ||
1214 | 1252 | ||
1215 | intel_panel_enable_backlight(dev, pipe); | 1253 | intel_panel_enable_backlight(dev, pipe); |
1216 | } | 1254 | } |
@@ -1220,6 +1258,7 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp) | |||
1220 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1258 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
1221 | struct drm_i915_private *dev_priv = dev->dev_private; | 1259 | struct drm_i915_private *dev_priv = dev->dev_private; |
1222 | u32 pp; | 1260 | u32 pp; |
1261 | u32 pp_ctrl_reg; | ||
1223 | 1262 | ||
1224 | if (!is_edp(intel_dp)) | 1263 | if (!is_edp(intel_dp)) |
1225 | return; | 1264 | return; |
@@ -1227,10 +1266,13 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp) | |||
1227 | intel_panel_disable_backlight(dev); | 1266 | intel_panel_disable_backlight(dev); |
1228 | 1267 | ||
1229 | DRM_DEBUG_KMS("\n"); | 1268 | DRM_DEBUG_KMS("\n"); |
1230 | pp = ironlake_get_pp_control(dev_priv); | 1269 | pp = ironlake_get_pp_control(intel_dp); |
1231 | pp &= ~EDP_BLC_ENABLE; | 1270 | pp &= ~EDP_BLC_ENABLE; |
1232 | I915_WRITE(PCH_PP_CONTROL, pp); | 1271 | |
1233 | POSTING_READ(PCH_PP_CONTROL); | 1272 | pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; |
1273 | |||
1274 | I915_WRITE(pp_ctrl_reg, pp); | ||
1275 | POSTING_READ(pp_ctrl_reg); | ||
1234 | msleep(intel_dp->backlight_off_delay); | 1276 | msleep(intel_dp->backlight_off_delay); |
1235 | } | 1277 | } |
1236 | 1278 | ||
@@ -2620,15 +2662,28 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, | |||
2620 | struct drm_i915_private *dev_priv = dev->dev_private; | 2662 | struct drm_i915_private *dev_priv = dev->dev_private; |
2621 | struct edp_power_seq cur, vbt, spec, final; | 2663 | struct edp_power_seq cur, vbt, spec, final; |
2622 | u32 pp_on, pp_off, pp_div, pp; | 2664 | u32 pp_on, pp_off, pp_div, pp; |
2665 | int pp_control_reg, pp_on_reg, pp_off_reg, pp_div_reg; | ||
2666 | |||
2667 | if (HAS_PCH_SPLIT(dev)) { | ||
2668 | pp_control_reg = PCH_PP_CONTROL; | ||
2669 | pp_on_reg = PCH_PP_ON_DELAYS; | ||
2670 | pp_off_reg = PCH_PP_OFF_DELAYS; | ||
2671 | pp_div_reg = PCH_PP_DIVISOR; | ||
2672 | } else { | ||
2673 | pp_control_reg = PIPEA_PP_CONTROL; | ||
2674 | pp_on_reg = PIPEA_PP_ON_DELAYS; | ||
2675 | pp_off_reg = PIPEA_PP_OFF_DELAYS; | ||
2676 | pp_div_reg = PIPEA_PP_DIVISOR; | ||
2677 | } | ||
2623 | 2678 | ||
2624 | /* Workaround: Need to write PP_CONTROL with the unlock key as | 2679 | /* Workaround: Need to write PP_CONTROL with the unlock key as |
2625 | * the very first thing. */ | 2680 | * the very first thing. */ |
2626 | pp = ironlake_get_pp_control(dev_priv); | 2681 | pp = ironlake_get_pp_control(intel_dp); |
2627 | I915_WRITE(PCH_PP_CONTROL, pp); | 2682 | I915_WRITE(pp_control_reg, pp); |
2628 | 2683 | ||
2629 | pp_on = I915_READ(PCH_PP_ON_DELAYS); | 2684 | pp_on = I915_READ(pp_on_reg); |
2630 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); | 2685 | pp_off = I915_READ(pp_off_reg); |
2631 | pp_div = I915_READ(PCH_PP_DIVISOR); | 2686 | pp_div = I915_READ(pp_div_reg); |
2632 | 2687 | ||
2633 | /* Pull timing values out of registers */ | 2688 | /* Pull timing values out of registers */ |
2634 | cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> | 2689 | cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> |
@@ -2703,7 +2758,22 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | |||
2703 | struct edp_power_seq *seq) | 2758 | struct edp_power_seq *seq) |
2704 | { | 2759 | { |
2705 | struct drm_i915_private *dev_priv = dev->dev_private; | 2760 | struct drm_i915_private *dev_priv = dev->dev_private; |
2706 | u32 pp_on, pp_off, pp_div; | 2761 | u32 pp_on, pp_off, pp_div, port_sel = 0; |
2762 | int div = HAS_PCH_SPLIT(dev) ? intel_pch_rawclk(dev) : intel_hrawclk(dev); | ||
2763 | int pp_on_reg, pp_off_reg, pp_div_reg; | ||
2764 | |||
2765 | if (HAS_PCH_SPLIT(dev)) { | ||
2766 | pp_on_reg = PCH_PP_ON_DELAYS; | ||
2767 | pp_off_reg = PCH_PP_OFF_DELAYS; | ||
2768 | pp_div_reg = PCH_PP_DIVISOR; | ||
2769 | } else { | ||
2770 | pp_on_reg = PIPEA_PP_ON_DELAYS; | ||
2771 | pp_off_reg = PIPEA_PP_OFF_DELAYS; | ||
2772 | pp_div_reg = PIPEA_PP_DIVISOR; | ||
2773 | } | ||
2774 | |||
2775 | if (IS_VALLEYVIEW(dev)) | ||
2776 | port_sel = I915_READ(pp_on_reg) & 0xc0000000; | ||
2707 | 2777 | ||
2708 | /* And finally store the new values in the power sequencer. */ | 2778 | /* And finally store the new values in the power sequencer. */ |
2709 | pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | | 2779 | pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | |
@@ -2712,8 +2782,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | |||
2712 | (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT); | 2782 | (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT); |
2713 | /* Compute the divisor for the pp clock, simply match the Bspec | 2783 | /* Compute the divisor for the pp clock, simply match the Bspec |
2714 | * formula. */ | 2784 | * formula. */ |
2715 | pp_div = ((100 * intel_pch_rawclk(dev))/2 - 1) | 2785 | pp_div = ((100 * div)/2 - 1) << PP_REFERENCE_DIVIDER_SHIFT; |
2716 | << PP_REFERENCE_DIVIDER_SHIFT; | ||
2717 | pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000) | 2786 | pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000) |
2718 | << PANEL_POWER_CYCLE_DELAY_SHIFT); | 2787 | << PANEL_POWER_CYCLE_DELAY_SHIFT); |
2719 | 2788 | ||
@@ -2721,19 +2790,21 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | |||
2721 | * power sequencer any more. */ | 2790 | * power sequencer any more. */ |
2722 | if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) { | 2791 | if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) { |
2723 | if (is_cpu_edp(intel_dp)) | 2792 | if (is_cpu_edp(intel_dp)) |
2724 | pp_on |= PANEL_POWER_PORT_DP_A; | 2793 | port_sel = PANEL_POWER_PORT_DP_A; |
2725 | else | 2794 | else |
2726 | pp_on |= PANEL_POWER_PORT_DP_D; | 2795 | port_sel = PANEL_POWER_PORT_DP_D; |
2727 | } | 2796 | } |
2728 | 2797 | ||
2729 | I915_WRITE(PCH_PP_ON_DELAYS, pp_on); | 2798 | pp_on |= port_sel; |
2730 | I915_WRITE(PCH_PP_OFF_DELAYS, pp_off); | 2799 | |
2731 | I915_WRITE(PCH_PP_DIVISOR, pp_div); | 2800 | I915_WRITE(pp_on_reg, pp_on); |
2801 | I915_WRITE(pp_off_reg, pp_off); | ||
2802 | I915_WRITE(pp_div_reg, pp_div); | ||
2732 | 2803 | ||
2733 | DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n", | 2804 | DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n", |
2734 | I915_READ(PCH_PP_ON_DELAYS), | 2805 | I915_READ(pp_on_reg), |
2735 | I915_READ(PCH_PP_OFF_DELAYS), | 2806 | I915_READ(pp_off_reg), |
2736 | I915_READ(PCH_PP_DIVISOR)); | 2807 | I915_READ(pp_div_reg)); |
2737 | } | 2808 | } |
2738 | 2809 | ||
2739 | void | 2810 | void |