aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-01-04 18:09:30 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2011-01-19 07:35:49 -0500
commitb24e71798871089da1a4ab049db2800afc1aac0c (patch)
treeb189257e13929f115641751061edbee8da861fa0 /drivers/gpu/drm/i915/intel_display.c
parent65993d64a31844ad444694efb2d159eb9c883e49 (diff)
drm/i915: add pipe/plane enable/disable functions
Add plane enable/disable functions to prevent duplicated code and allow us to easily check for plane enable/disable requirements (such as pipe enable, plane status, pll status etc). Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c308
1 files changed, 213 insertions, 95 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9dcad312b6e5..2bf72a4b069f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1058,6 +1058,203 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
1058 } 1058 }
1059} 1059}
1060 1060
1061static const char *state_string(bool enabled)
1062{
1063 return enabled ? "on" : "off";
1064}
1065
1066/* Only for pre-ILK configs */
1067static void assert_pll(struct drm_i915_private *dev_priv,
1068 enum pipe pipe, bool state)
1069{
1070 int reg;
1071 u32 val;
1072 bool cur_state;
1073
1074 reg = DPLL(pipe);
1075 val = I915_READ(reg);
1076 cur_state = !!(val & DPLL_VCO_ENABLE);
1077 WARN(cur_state != state,
1078 "PLL state assertion failure (expected %s, current %s)\n",
1079 state_string(state), state_string(cur_state));
1080}
1081#define assert_pll_enabled(d, p) assert_pll(d, p, true)
1082#define assert_pll_disabled(d, p) assert_pll(d, p, false)
1083
1084static void assert_pipe_enabled(struct drm_i915_private *dev_priv,
1085 enum pipe pipe)
1086{
1087 int reg;
1088 u32 val;
1089
1090 reg = PIPECONF(pipe);
1091 val = I915_READ(reg);
1092 WARN(!(val & PIPECONF_ENABLE),
1093 "pipe %c assertion failure, should be active but is disabled\n",
1094 pipe ? 'B' : 'A');
1095}
1096
1097static void assert_plane_enabled(struct drm_i915_private *dev_priv,
1098 enum plane plane)
1099{
1100 int reg;
1101 u32 val;
1102
1103 reg = DSPCNTR(plane);
1104 val = I915_READ(reg);
1105 WARN(!(val & DISPLAY_PLANE_ENABLE),
1106 "plane %c assertion failure, should be active but is disabled\n",
1107 plane ? 'B' : 'A');
1108}
1109
1110static void assert_planes_disabled(struct drm_i915_private *dev_priv,
1111 enum pipe pipe)
1112{
1113 int reg, i;
1114 u32 val;
1115 int cur_pipe;
1116
1117 /* Need to check both planes against the pipe */
1118 for (i = 0; i < 2; i++) {
1119 reg = DSPCNTR(i);
1120 val = I915_READ(reg);
1121 cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
1122 DISPPLANE_SEL_PIPE_SHIFT;
1123 WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe,
1124 "plane %d assertion failure, should be off on pipe %c but is still active\n",
1125 i, pipe ? 'B' : 'A');
1126 }
1127}
1128
1129/**
1130 * intel_enable_pipe - enable a pipe, assertiing requirements
1131 * @dev_priv: i915 private structure
1132 * @pipe: pipe to enable
1133 *
1134 * Enable @pipe, making sure that various hardware specific requirements
1135 * are met, if applicable, e.g. PLL enabled, LVDS pairs enabled, etc.
1136 *
1137 * @pipe should be %PIPE_A or %PIPE_B.
1138 *
1139 * Will wait until the pipe is actually running (i.e. first vblank) before
1140 * returning.
1141 */
1142static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
1143{
1144 int reg;
1145 u32 val;
1146
1147 /*
1148 * A pipe without a PLL won't actually be able to drive bits from
1149 * a plane. On ILK+ the pipe PLLs are integrated, so we don't
1150 * need the check.
1151 */
1152 if (!HAS_PCH_SPLIT(dev_priv->dev))
1153 assert_pll_enabled(dev_priv, pipe);
1154
1155 reg = PIPECONF(pipe);
1156 val = I915_READ(reg);
1157 val |= PIPECONF_ENABLE;
1158 I915_WRITE(reg, val);
1159 POSTING_READ(reg);
1160 intel_wait_for_vblank(dev_priv->dev, pipe);
1161}
1162
1163/**
1164 * intel_disable_pipe - disable a pipe, assertiing requirements
1165 * @dev_priv: i915 private structure
1166 * @pipe: pipe to disable
1167 *
1168 * Disable @pipe, making sure that various hardware specific requirements
1169 * are met, if applicable, e.g. plane disabled, panel fitter off, etc.
1170 *
1171 * @pipe should be %PIPE_A or %PIPE_B.
1172 *
1173 * Will wait until the pipe has shut down before returning.
1174 */
1175static void intel_disable_pipe(struct drm_i915_private *dev_priv,
1176 enum pipe pipe)
1177{
1178 int reg;
1179 u32 val;
1180
1181 /*
1182 * Make sure planes won't keep trying to pump pixels to us,
1183 * or we might hang the display.
1184 */
1185 assert_planes_disabled(dev_priv, pipe);
1186
1187 /* Don't disable pipe A or pipe A PLLs if needed */
1188 if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
1189 return;
1190
1191 reg = PIPECONF(pipe);
1192 val = I915_READ(reg);
1193 val &= ~PIPECONF_ENABLE;
1194 I915_WRITE(reg, val);
1195 POSTING_READ(reg);
1196 intel_wait_for_pipe_off(dev_priv->dev, pipe);
1197}
1198
1199/**
1200 * intel_enable_plane - enable a display plane on a given pipe
1201 * @dev_priv: i915 private structure
1202 * @plane: plane to enable
1203 * @pipe: pipe being fed
1204 *
1205 * Enable @plane on @pipe, making sure that @pipe is running first.
1206 */
1207static void intel_enable_plane(struct drm_i915_private *dev_priv,
1208 enum plane plane, enum pipe pipe)
1209{
1210 int reg;
1211 u32 val;
1212
1213 /* If the pipe isn't enabled, we can't pump pixels and may hang */
1214 assert_pipe_enabled(dev_priv, pipe);
1215
1216 reg = DSPCNTR(plane);
1217 val = I915_READ(reg);
1218 val |= DISPLAY_PLANE_ENABLE;
1219 I915_WRITE(reg, val);
1220 POSTING_READ(reg);
1221 intel_wait_for_vblank(dev_priv->dev, pipe);
1222}
1223
1224/*
1225 * Plane regs are double buffered, going from enabled->disabled needs a
1226 * trigger in order to latch. The display address reg provides this.
1227 */
1228static void intel_flush_display_plane(struct drm_i915_private *dev_priv,
1229 enum plane plane)
1230{
1231 u32 reg = DSPADDR(plane);
1232 I915_WRITE(reg, I915_READ(reg));
1233}
1234
1235/**
1236 * intel_disable_plane - disable a display plane
1237 * @dev_priv: i915 private structure
1238 * @plane: plane to disable
1239 * @pipe: pipe consuming the data
1240 *
1241 * Disable @plane; should be an independent operation.
1242 */
1243static void intel_disable_plane(struct drm_i915_private *dev_priv,
1244 enum plane plane, enum pipe pipe)
1245{
1246 int reg;
1247 u32 val;
1248
1249 reg = DSPCNTR(plane);
1250 val = I915_READ(reg);
1251 val &= ~DISPLAY_PLANE_ENABLE;
1252 I915_WRITE(reg, val);
1253 POSTING_READ(reg);
1254 intel_flush_display_plane(dev_priv, plane);
1255 intel_wait_for_vblank(dev_priv->dev, pipe);
1256}
1257
1061static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) 1258static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
1062{ 1259{
1063 struct drm_device *dev = crtc->dev; 1260 struct drm_device *dev = crtc->dev;
@@ -1982,14 +2179,6 @@ static void ironlake_fdi_enable(struct drm_crtc *crtc)
1982 } 2179 }
1983} 2180}
1984 2181
1985static void intel_flush_display_plane(struct drm_device *dev,
1986 int plane)
1987{
1988 struct drm_i915_private *dev_priv = dev->dev_private;
1989 u32 reg = DSPADDR(plane);
1990 I915_WRITE(reg, I915_READ(reg));
1991}
1992
1993/* 2182/*
1994 * When we disable a pipe, we need to clear any pending scanline wait events 2183 * When we disable a pipe, we need to clear any pending scanline wait events
1995 * to avoid hanging the ring, which we assume we are waiting on. 2184 * to avoid hanging the ring, which we assume we are waiting on.
@@ -2062,22 +2251,8 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
2062 dev_priv->pch_pf_size); 2251 dev_priv->pch_pf_size);
2063 } 2252 }
2064 2253
2065 /* Enable CPU pipe */ 2254 intel_enable_pipe(dev_priv, pipe);
2066 reg = PIPECONF(pipe); 2255 intel_enable_plane(dev_priv, plane, pipe);
2067 temp = I915_READ(reg);
2068 if ((temp & PIPECONF_ENABLE) == 0) {
2069 I915_WRITE(reg, temp | PIPECONF_ENABLE);
2070 POSTING_READ(reg);
2071 intel_wait_for_vblank(dev, intel_crtc->pipe);
2072 }
2073
2074 /* configure and enable CPU plane */
2075 reg = DSPCNTR(plane);
2076 temp = I915_READ(reg);
2077 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
2078 I915_WRITE(reg, temp | DISPLAY_PLANE_ENABLE);
2079 intel_flush_display_plane(dev, plane);
2080 }
2081 2256
2082 /* For PCH output, training FDI link */ 2257 /* For PCH output, training FDI link */
2083 if (IS_GEN6(dev)) 2258 if (IS_GEN6(dev))
@@ -2185,27 +2360,13 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
2185 drm_vblank_off(dev, pipe); 2360 drm_vblank_off(dev, pipe);
2186 intel_crtc_update_cursor(crtc, false); 2361 intel_crtc_update_cursor(crtc, false);
2187 2362
2188 /* Disable display plane */ 2363 intel_disable_plane(dev_priv, plane, pipe);
2189 reg = DSPCNTR(plane);
2190 temp = I915_READ(reg);
2191 if (temp & DISPLAY_PLANE_ENABLE) {
2192 I915_WRITE(reg, temp & ~DISPLAY_PLANE_ENABLE);
2193 intel_flush_display_plane(dev, plane);
2194 }
2195 2364
2196 if (dev_priv->cfb_plane == plane && 2365 if (dev_priv->cfb_plane == plane &&
2197 dev_priv->display.disable_fbc) 2366 dev_priv->display.disable_fbc)
2198 dev_priv->display.disable_fbc(dev); 2367 dev_priv->display.disable_fbc(dev);
2199 2368
2200 /* disable cpu pipe, disable after all planes disabled */ 2369 intel_disable_pipe(dev_priv, pipe);
2201 reg = PIPECONF(pipe);
2202 temp = I915_READ(reg);
2203 if (temp & PIPECONF_ENABLE) {
2204 I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
2205 POSTING_READ(reg);
2206 /* wait for cpu pipe off, pipe state */
2207 intel_wait_for_pipe_off(dev, intel_crtc->pipe);
2208 }
2209 2370
2210 /* Disable PF */ 2371 /* Disable PF */
2211 I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0); 2372 I915_WRITE(pipe ? PFB_CTL_1 : PFA_CTL_1, 0);
@@ -2400,19 +2561,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
2400 udelay(150); 2561 udelay(150);
2401 } 2562 }
2402 2563
2403 /* Enable the pipe */ 2564 intel_enable_pipe(dev_priv, pipe);
2404 reg = PIPECONF(pipe); 2565 intel_enable_plane(dev_priv, plane, pipe);
2405 temp = I915_READ(reg);
2406 if ((temp & PIPECONF_ENABLE) == 0)
2407 I915_WRITE(reg, temp | PIPECONF_ENABLE);
2408
2409 /* Enable the plane */
2410 reg = DSPCNTR(plane);
2411 temp = I915_READ(reg);
2412 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
2413 I915_WRITE(reg, temp | DISPLAY_PLANE_ENABLE);
2414 intel_flush_display_plane(dev, plane);
2415 }
2416 2566
2417 intel_crtc_load_lut(crtc); 2567 intel_crtc_load_lut(crtc);
2418 intel_update_fbc(dev); 2568 intel_update_fbc(dev);
@@ -2444,33 +2594,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
2444 dev_priv->display.disable_fbc) 2594 dev_priv->display.disable_fbc)
2445 dev_priv->display.disable_fbc(dev); 2595 dev_priv->display.disable_fbc(dev);
2446 2596
2447 /* Disable display plane */ 2597 intel_disable_plane(dev_priv, plane, pipe);
2448 reg = DSPCNTR(plane);
2449 temp = I915_READ(reg);
2450 if (temp & DISPLAY_PLANE_ENABLE) {
2451 I915_WRITE(reg, temp & ~DISPLAY_PLANE_ENABLE);
2452 /* Flush the plane changes */
2453 intel_flush_display_plane(dev, plane);
2454
2455 /* Wait for vblank for the disable to take effect */
2456 if (IS_GEN2(dev))
2457 intel_wait_for_vblank(dev, pipe);
2458 }
2459 2598
2460 /* Don't disable pipe A or pipe A PLLs if needed */ 2599 /* Don't disable pipe A or pipe A PLLs if needed */
2461 if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) 2600 if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
2462 goto done; 2601 goto done;
2463 2602
2464 /* Next, disable display pipes */ 2603 intel_disable_pipe(dev_priv, pipe);
2465 reg = PIPECONF(pipe);
2466 temp = I915_READ(reg);
2467 if (temp & PIPECONF_ENABLE) {
2468 I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
2469
2470 /* Wait for the pipe to turn off */
2471 POSTING_READ(reg);
2472 intel_wait_for_pipe_off(dev, pipe);
2473 }
2474 2604
2475 reg = DPLL(pipe); 2605 reg = DPLL(pipe);
2476 temp = I915_READ(reg); 2606 temp = I915_READ(reg);
@@ -4222,11 +4352,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
4222 pipeconf &= ~PIPECONF_DOUBLE_WIDE; 4352 pipeconf &= ~PIPECONF_DOUBLE_WIDE;
4223 } 4353 }
4224 4354
4225 if (!HAS_PCH_SPLIT(dev)) { 4355 if (!HAS_PCH_SPLIT(dev))
4226 dspcntr |= DISPLAY_PLANE_ENABLE;
4227 pipeconf |= PIPECONF_ENABLE;
4228 dpll |= DPLL_VCO_ENABLE; 4356 dpll |= DPLL_VCO_ENABLE;
4229 }
4230 4357
4231 DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); 4358 DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
4232 drm_mode_debug_printmodeline(mode); 4359 drm_mode_debug_printmodeline(mode);
@@ -4435,6 +4562,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
4435 4562
4436 I915_WRITE(PIPECONF(pipe), pipeconf); 4563 I915_WRITE(PIPECONF(pipe), pipeconf);
4437 POSTING_READ(PIPECONF(pipe)); 4564 POSTING_READ(PIPECONF(pipe));
4565 if (!HAS_PCH_SPLIT(dev))
4566 intel_enable_pipe(dev_priv, pipe);
4438 4567
4439 intel_wait_for_vblank(dev, pipe); 4568 intel_wait_for_vblank(dev, pipe);
4440 4569
@@ -4445,6 +4574,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
4445 } 4574 }
4446 4575
4447 I915_WRITE(DSPCNTR(plane), dspcntr); 4576 I915_WRITE(DSPCNTR(plane), dspcntr);
4577 POSTING_READ(DSPCNTR(plane));
4578 if (!HAS_PCH_SPLIT(dev))
4579 intel_enable_plane(dev_priv, plane, pipe);
4448 4580
4449 ret = intel_pipe_set_base(crtc, x, y, old_fb); 4581 ret = intel_pipe_set_base(crtc, x, y, old_fb);
4450 4582
@@ -5583,22 +5715,8 @@ static void intel_sanitize_modesetting(struct drm_device *dev,
5583 pipe = !pipe; 5715 pipe = !pipe;
5584 5716
5585 /* Disable the plane and wait for it to stop reading from the pipe. */ 5717 /* Disable the plane and wait for it to stop reading from the pipe. */
5586 I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); 5718 intel_disable_plane(dev_priv, plane, pipe);
5587 intel_flush_display_plane(dev, plane); 5719 intel_disable_pipe(dev_priv, pipe);
5588
5589 if (IS_GEN2(dev))
5590 intel_wait_for_vblank(dev, pipe);
5591
5592 if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
5593 return;
5594
5595 /* Switch off the pipe. */
5596 reg = PIPECONF(pipe);
5597 val = I915_READ(reg);
5598 if (val & PIPECONF_ENABLE) {
5599 I915_WRITE(reg, val & ~PIPECONF_ENABLE);
5600 intel_wait_for_pipe_off(dev, pipe);
5601 }
5602} 5720}
5603 5721
5604static void intel_crtc_init(struct drm_device *dev, int pipe) 5722static void intel_crtc_init(struct drm_device *dev, int pipe)