diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 56 |
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; |