aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyuw@linux.intel.com>2009-07-23 13:00:29 -0400
committerEric Anholt <eric@anholt.net>2009-07-29 18:16:01 -0400
commit249c0e64c24bf455a4e4815f72750f2b16cedd94 (patch)
tree0a75d3f0f48acdd5341a9670dc7c860af7669940 /drivers/gpu/drm
parent24f119c769bacac5729297b682fec7811a983cc6 (diff)
drm/i915: fix issue in display pipe setup on IGDNG
During pipe DPMS off, instead of busy waiting pipe off, insert delays during wait and don't loop after enough tries which matches spec requirement. Also try to match DPMS on path by disable FDI TX PLL in DPMS off. Disable PF by writing PF_WIN_SZ which really trigger the update. Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c56
2 files changed, 46 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 897a116cad14..7c77c4c53c52 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1848,6 +1848,8 @@
1848#define PFA_CTL_1 0x68080 1848#define PFA_CTL_1 0x68080
1849#define PFB_CTL_1 0x68880 1849#define PFB_CTL_1 0x68880
1850#define PF_ENABLE (1<<31) 1850#define PF_ENABLE (1<<31)
1851#define PFA_WIN_SZ 0x68074
1852#define PFB_WIN_SZ 0x68874
1851 1853
1852/* legacy palette */ 1854/* legacy palette */
1853#define LGC_PALETTE_A 0x4a000 1855#define LGC_PALETTE_A 0x4a000
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b06364ed2591..15a8c3908acb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1038,6 +1038,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
1038 int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; 1038 int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR;
1039 int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; 1039 int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF;
1040 int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; 1040 int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1;
1041 int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ;
1041 int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; 1042 int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
1042 int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; 1043 int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
1043 int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; 1044 int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
@@ -1051,7 +1052,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
1051 int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B; 1052 int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B;
1052 int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; 1053 int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B;
1053 u32 temp; 1054 u32 temp;
1054 int tries = 5, j; 1055 int tries = 5, j, n;
1055 1056
1056 /* XXX: When our outputs are all unaware of DPMS modes other than off 1057 /* XXX: When our outputs are all unaware of DPMS modes other than off
1057 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. 1058 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
@@ -1239,19 +1240,21 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
1239 if ((temp & PIPEACONF_ENABLE) != 0) { 1240 if ((temp & PIPEACONF_ENABLE) != 0) {
1240 I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); 1241 I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
1241 I915_READ(pipeconf_reg); 1242 I915_READ(pipeconf_reg);
1243 n = 0;
1242 /* wait for cpu pipe off, pipe state */ 1244 /* wait for cpu pipe off, pipe state */
1243 while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) 1245 while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) {
1244 ; 1246 n++;
1247 if (n < 60) {
1248 udelay(500);
1249 continue;
1250 } else {
1251 DRM_DEBUG("pipe %d off delay\n", pipe);
1252 break;
1253 }
1254 }
1245 } else 1255 } else
1246 DRM_DEBUG("crtc %d is disabled\n", pipe); 1256 DRM_DEBUG("crtc %d is disabled\n", pipe);
1247 1257
1248 /* IGDNG-A : disable cpu panel fitter ? */
1249 temp = I915_READ(pf_ctl_reg);
1250 if ((temp & PF_ENABLE) != 0) {
1251 I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
1252 I915_READ(pf_ctl_reg);
1253 }
1254
1255 /* disable CPU FDI tx and PCH FDI rx */ 1258 /* disable CPU FDI tx and PCH FDI rx */
1256 temp = I915_READ(fdi_tx_reg); 1259 temp = I915_READ(fdi_tx_reg);
1257 I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_ENABLE); 1260 I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_ENABLE);
@@ -1261,6 +1264,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
1261 I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE); 1264 I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE);
1262 I915_READ(fdi_rx_reg); 1265 I915_READ(fdi_rx_reg);
1263 1266
1267 udelay(100);
1268
1264 /* still set train pattern 1 */ 1269 /* still set train pattern 1 */
1265 temp = I915_READ(fdi_tx_reg); 1270 temp = I915_READ(fdi_tx_reg);
1266 temp &= ~FDI_LINK_TRAIN_NONE; 1271 temp &= ~FDI_LINK_TRAIN_NONE;
@@ -1272,14 +1277,25 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
1272 temp |= FDI_LINK_TRAIN_PATTERN_1; 1277 temp |= FDI_LINK_TRAIN_PATTERN_1;
1273 I915_WRITE(fdi_rx_reg, temp); 1278 I915_WRITE(fdi_rx_reg, temp);
1274 1279
1280 udelay(100);
1281
1275 /* disable PCH transcoder */ 1282 /* disable PCH transcoder */
1276 temp = I915_READ(transconf_reg); 1283 temp = I915_READ(transconf_reg);
1277 if ((temp & TRANS_ENABLE) != 0) { 1284 if ((temp & TRANS_ENABLE) != 0) {
1278 I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); 1285 I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE);
1279 I915_READ(transconf_reg); 1286 I915_READ(transconf_reg);
1287 n = 0;
1280 /* wait for PCH transcoder off, transcoder state */ 1288 /* wait for PCH transcoder off, transcoder state */
1281 while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) 1289 while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) {
1282 ; 1290 n++;
1291 if (n < 60) {
1292 udelay(500);
1293 continue;
1294 } else {
1295 DRM_DEBUG("transcoder %d off delay\n", pipe);
1296 break;
1297 }
1298 }
1283 } 1299 }
1284 1300
1285 /* disable PCH DPLL */ 1301 /* disable PCH DPLL */
@@ -1297,6 +1313,22 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
1297 I915_READ(fdi_rx_reg); 1313 I915_READ(fdi_rx_reg);
1298 } 1314 }
1299 1315
1316 /* Disable CPU FDI TX PLL */
1317 temp = I915_READ(fdi_tx_reg);
1318 if ((temp & FDI_TX_PLL_ENABLE) != 0) {
1319 I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE);
1320 I915_READ(fdi_tx_reg);
1321 udelay(100);
1322 }
1323
1324 /* Disable PF */
1325 temp = I915_READ(pf_ctl_reg);
1326 if ((temp & PF_ENABLE) != 0) {
1327 I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
1328 I915_READ(pf_ctl_reg);
1329 }
1330 I915_WRITE(pf_win_size, 0);
1331
1300 /* Wait for the clocks to turn off. */ 1332 /* Wait for the clocks to turn off. */
1301 udelay(150); 1333 udelay(150);
1302 break; 1334 break;