aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2011-07-28 19:30:41 -0400
committerKeith Packard <keithp@keithp.com>2011-07-28 19:30:41 -0400
commit2c1756b12edc19fdd75c833699cb752e1bbb641e (patch)
tree2893f6f8b59bfea0e295877643dc29849a7d1a67 /drivers/gpu/drm/i915/intel_display.c
parentcf96e46fcd147856fd8151fab91c410f0ec16c47 (diff)
parentd74362c9e45689d8d7e3d4bcf6681c4358ef4f2e (diff)
Merge branch 'drm-intel-fixes' into drm-intel-next
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c82
1 files changed, 58 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 97d28013db79..ce908ec02900 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -980,11 +980,29 @@ static void assert_transcoder_disabled(struct drm_i915_private *dev_priv,
980 pipe_name(pipe)); 980 pipe_name(pipe));
981} 981}
982 982
983static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe,
984 int reg, u32 port_sel, u32 val)
985{
986 if ((val & DP_PORT_EN) == 0)
987 return false;
988
989 if (HAS_PCH_CPT(dev_priv->dev)) {
990 u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe);
991 u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg);
992 if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
993 return false;
994 } else {
995 if ((val & DP_PIPE_MASK) != (pipe << 30))
996 return false;
997 }
998 return true;
999}
1000
983static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, 1001static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
984 enum pipe pipe, int reg) 1002 enum pipe pipe, int reg, u32 port_sel)
985{ 1003{
986 u32 val = I915_READ(reg); 1004 u32 val = I915_READ(reg);
987 WARN(DP_PIPE_ENABLED(val, pipe), 1005 WARN(dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val),
988 "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", 1006 "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
989 reg, pipe_name(pipe)); 1007 reg, pipe_name(pipe));
990} 1008}
@@ -1004,9 +1022,9 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
1004 int reg; 1022 int reg;
1005 u32 val; 1023 u32 val;
1006 1024
1007 assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B); 1025 assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B);
1008 assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C); 1026 assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C);
1009 assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D); 1027 assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D);
1010 1028
1011 reg = PCH_ADPA; 1029 reg = PCH_ADPA;
1012 val = I915_READ(reg); 1030 val = I915_READ(reg);
@@ -1276,6 +1294,17 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv,
1276 intel_wait_for_pipe_off(dev_priv->dev, pipe); 1294 intel_wait_for_pipe_off(dev_priv->dev, pipe);
1277} 1295}
1278 1296
1297/*
1298 * Plane regs are double buffered, going from enabled->disabled needs a
1299 * trigger in order to latch. The display address reg provides this.
1300 */
1301static void intel_flush_display_plane(struct drm_i915_private *dev_priv,
1302 enum plane plane)
1303{
1304 I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane)));
1305 I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane)));
1306}
1307
1279/** 1308/**
1280 * intel_enable_plane - enable a display plane on a given pipe 1309 * intel_enable_plane - enable a display plane on a given pipe
1281 * @dev_priv: i915 private structure 1310 * @dev_priv: i915 private structure
@@ -1299,20 +1328,10 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv,
1299 return; 1328 return;
1300 1329
1301 I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); 1330 I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE);
1331 intel_flush_display_plane(dev_priv, plane);
1302 intel_wait_for_vblank(dev_priv->dev, pipe); 1332 intel_wait_for_vblank(dev_priv->dev, pipe);
1303} 1333}
1304 1334
1305/*
1306 * Plane regs are double buffered, going from enabled->disabled needs a
1307 * trigger in order to latch. The display address reg provides this.
1308 */
1309static void intel_flush_display_plane(struct drm_i915_private *dev_priv,
1310 enum plane plane)
1311{
1312 u32 reg = DSPADDR(plane);
1313 I915_WRITE(reg, I915_READ(reg));
1314}
1315
1316/** 1335/**
1317 * intel_disable_plane - disable a display plane 1336 * intel_disable_plane - disable a display plane
1318 * @dev_priv: i915 private structure 1337 * @dev_priv: i915 private structure
@@ -1338,19 +1357,24 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv,
1338} 1357}
1339 1358
1340static void disable_pch_dp(struct drm_i915_private *dev_priv, 1359static void disable_pch_dp(struct drm_i915_private *dev_priv,
1341 enum pipe pipe, int reg) 1360 enum pipe pipe, int reg, u32 port_sel)
1342{ 1361{
1343 u32 val = I915_READ(reg); 1362 u32 val = I915_READ(reg);
1344 if (DP_PIPE_ENABLED(val, pipe)) 1363 if (dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val)) {
1364 DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe);
1345 I915_WRITE(reg, val & ~DP_PORT_EN); 1365 I915_WRITE(reg, val & ~DP_PORT_EN);
1366 }
1346} 1367}
1347 1368
1348static void disable_pch_hdmi(struct drm_i915_private *dev_priv, 1369static void disable_pch_hdmi(struct drm_i915_private *dev_priv,
1349 enum pipe pipe, int reg) 1370 enum pipe pipe, int reg)
1350{ 1371{
1351 u32 val = I915_READ(reg); 1372 u32 val = I915_READ(reg);
1352 if (HDMI_PIPE_ENABLED(val, pipe)) 1373 if (HDMI_PIPE_ENABLED(val, pipe)) {
1374 DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n",
1375 reg, pipe);
1353 I915_WRITE(reg, val & ~PORT_ENABLE); 1376 I915_WRITE(reg, val & ~PORT_ENABLE);
1377 }
1354} 1378}
1355 1379
1356/* Disable any ports connected to this transcoder */ 1380/* Disable any ports connected to this transcoder */
@@ -1362,9 +1386,9 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv,
1362 val = I915_READ(PCH_PP_CONTROL); 1386 val = I915_READ(PCH_PP_CONTROL);
1363 I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS); 1387 I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS);
1364 1388
1365 disable_pch_dp(dev_priv, pipe, PCH_DP_B); 1389 disable_pch_dp(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B);
1366 disable_pch_dp(dev_priv, pipe, PCH_DP_C); 1390 disable_pch_dp(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C);
1367 disable_pch_dp(dev_priv, pipe, PCH_DP_D); 1391 disable_pch_dp(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D);
1368 1392
1369 reg = PCH_ADPA; 1393 reg = PCH_ADPA;
1370 val = I915_READ(reg); 1394 val = I915_READ(reg);
@@ -5523,6 +5547,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
5523 5547
5524 drm_vblank_post_modeset(dev, pipe); 5548 drm_vblank_post_modeset(dev, pipe);
5525 5549
5550 intel_crtc->dpms_mode = DRM_MODE_DPMS_ON;
5551
5526 return ret; 5552 return ret;
5527} 5553}
5528 5554
@@ -7721,10 +7747,12 @@ static void gen6_init_clock_gating(struct drm_device *dev)
7721 ILK_DPARB_CLK_GATE | 7747 ILK_DPARB_CLK_GATE |
7722 ILK_DPFD_CLK_GATE); 7748 ILK_DPFD_CLK_GATE);
7723 7749
7724 for_each_pipe(pipe) 7750 for_each_pipe(pipe) {
7725 I915_WRITE(DSPCNTR(pipe), 7751 I915_WRITE(DSPCNTR(pipe),
7726 I915_READ(DSPCNTR(pipe)) | 7752 I915_READ(DSPCNTR(pipe)) |
7727 DISPPLANE_TRICKLE_FEED_DISABLE); 7753 DISPPLANE_TRICKLE_FEED_DISABLE);
7754 intel_flush_display_plane(dev_priv, pipe);
7755 }
7728} 7756}
7729 7757
7730static void ivybridge_init_clock_gating(struct drm_device *dev) 7758static void ivybridge_init_clock_gating(struct drm_device *dev)
@@ -7741,10 +7769,12 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
7741 7769
7742 I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); 7770 I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
7743 7771
7744 for_each_pipe(pipe) 7772 for_each_pipe(pipe) {
7745 I915_WRITE(DSPCNTR(pipe), 7773 I915_WRITE(DSPCNTR(pipe),
7746 I915_READ(DSPCNTR(pipe)) | 7774 I915_READ(DSPCNTR(pipe)) |
7747 DISPPLANE_TRICKLE_FEED_DISABLE); 7775 DISPPLANE_TRICKLE_FEED_DISABLE);
7776 intel_flush_display_plane(dev_priv, pipe);
7777 }
7748} 7778}
7749 7779
7750static void g4x_init_clock_gating(struct drm_device *dev) 7780static void g4x_init_clock_gating(struct drm_device *dev)
@@ -7827,6 +7857,7 @@ static void ibx_init_clock_gating(struct drm_device *dev)
7827static void cpt_init_clock_gating(struct drm_device *dev) 7857static void cpt_init_clock_gating(struct drm_device *dev)
7828{ 7858{
7829 struct drm_i915_private *dev_priv = dev->dev_private; 7859 struct drm_i915_private *dev_priv = dev->dev_private;
7860 int pipe;
7830 7861
7831 /* 7862 /*
7832 * On Ibex Peak and Cougar Point, we need to disable clock 7863 * On Ibex Peak and Cougar Point, we need to disable clock
@@ -7836,6 +7867,9 @@ static void cpt_init_clock_gating(struct drm_device *dev)
7836 I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); 7867 I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
7837 I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | 7868 I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
7838 DPLS_EDP_PPS_FIX_DIS); 7869 DPLS_EDP_PPS_FIX_DIS);
7870 /* Without this, mode sets may fail silently on FDI */
7871 for_each_pipe(pipe)
7872 I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS);
7839} 7873}
7840 7874
7841static void ironlake_teardown_rc6(struct drm_device *dev) 7875static void ironlake_teardown_rc6(struct drm_device *dev)