diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_suspend.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 251 |
1 files changed, 152 insertions, 99 deletions
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index a98e2831ed31..9e1d16e5c3ea 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -222,23 +222,12 @@ static void i915_restore_vga(struct drm_device *dev) | |||
222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); | 222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); |
223 | } | 223 | } |
224 | 224 | ||
225 | int i915_save_state(struct drm_device *dev) | 225 | static void i915_save_modeset_reg(struct drm_device *dev) |
226 | { | 226 | { |
227 | struct drm_i915_private *dev_priv = dev->dev_private; | 227 | struct drm_i915_private *dev_priv = dev->dev_private; |
228 | int i; | ||
229 | |||
230 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
231 | |||
232 | /* Render Standby */ | ||
233 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
234 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
235 | |||
236 | /* Hardware status page */ | ||
237 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
238 | |||
239 | /* Display arbitration control */ | ||
240 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
241 | 228 | ||
229 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
230 | return; | ||
242 | /* Pipe & plane A info */ | 231 | /* Pipe & plane A info */ |
243 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 232 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
244 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 233 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -294,7 +283,122 @@ int i915_save_state(struct drm_device *dev) | |||
294 | } | 283 | } |
295 | i915_save_palette(dev, PIPE_B); | 284 | i915_save_palette(dev, PIPE_B); |
296 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | 285 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); |
286 | return; | ||
287 | } | ||
288 | static void i915_restore_modeset_reg(struct drm_device *dev) | ||
289 | { | ||
290 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
291 | |||
292 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
293 | return; | ||
294 | |||
295 | /* Pipe & plane A info */ | ||
296 | /* Prime the clock */ | ||
297 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
298 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
299 | ~DPLL_VCO_ENABLE); | ||
300 | DRM_UDELAY(150); | ||
301 | } | ||
302 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
303 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
304 | /* Actually enable it */ | ||
305 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
306 | DRM_UDELAY(150); | ||
307 | if (IS_I965G(dev)) | ||
308 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
309 | DRM_UDELAY(150); | ||
310 | |||
311 | /* Restore mode */ | ||
312 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
313 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
314 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
315 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
316 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
317 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
318 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
319 | |||
320 | /* Restore plane info */ | ||
321 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
322 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
323 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
324 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
325 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
326 | if (IS_I965G(dev)) { | ||
327 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
328 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
329 | } | ||
330 | |||
331 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
332 | |||
333 | i915_restore_palette(dev, PIPE_A); | ||
334 | /* Enable the plane */ | ||
335 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
336 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
337 | |||
338 | /* Pipe & plane B info */ | ||
339 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
340 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
341 | ~DPLL_VCO_ENABLE); | ||
342 | DRM_UDELAY(150); | ||
343 | } | ||
344 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
345 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
346 | /* Actually enable it */ | ||
347 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
348 | DRM_UDELAY(150); | ||
349 | if (IS_I965G(dev)) | ||
350 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
351 | DRM_UDELAY(150); | ||
352 | |||
353 | /* Restore mode */ | ||
354 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
355 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
356 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
357 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
358 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
359 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
360 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
361 | |||
362 | /* Restore plane info */ | ||
363 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
364 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
365 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
366 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
367 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
368 | if (IS_I965G(dev)) { | ||
369 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
370 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
371 | } | ||
372 | |||
373 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
374 | |||
375 | i915_restore_palette(dev, PIPE_B); | ||
376 | /* Enable the plane */ | ||
377 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
378 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
297 | 379 | ||
380 | return; | ||
381 | } | ||
382 | int i915_save_state(struct drm_device *dev) | ||
383 | { | ||
384 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
385 | int i; | ||
386 | |||
387 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
388 | |||
389 | /* Render Standby */ | ||
390 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
391 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
392 | |||
393 | /* Hardware status page */ | ||
394 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
395 | |||
396 | /* Display arbitration control */ | ||
397 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
398 | |||
399 | /* This is only meaningful in non-KMS mode */ | ||
400 | /* Don't save them in KMS mode */ | ||
401 | i915_save_modeset_reg(dev); | ||
298 | /* Cursor state */ | 402 | /* Cursor state */ |
299 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); | 403 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); |
300 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); | 404 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); |
@@ -322,6 +426,20 @@ int i915_save_state(struct drm_device *dev) | |||
322 | dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); | 426 | dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); |
323 | dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); | 427 | dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); |
324 | 428 | ||
429 | /* Display Port state */ | ||
430 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
431 | dev_priv->saveDP_B = I915_READ(DP_B); | ||
432 | dev_priv->saveDP_C = I915_READ(DP_C); | ||
433 | dev_priv->saveDP_D = I915_READ(DP_D); | ||
434 | dev_priv->savePIPEA_GMCH_DATA_M = I915_READ(PIPEA_GMCH_DATA_M); | ||
435 | dev_priv->savePIPEB_GMCH_DATA_M = I915_READ(PIPEB_GMCH_DATA_M); | ||
436 | dev_priv->savePIPEA_GMCH_DATA_N = I915_READ(PIPEA_GMCH_DATA_N); | ||
437 | dev_priv->savePIPEB_GMCH_DATA_N = I915_READ(PIPEB_GMCH_DATA_N); | ||
438 | dev_priv->savePIPEA_DP_LINK_M = I915_READ(PIPEA_DP_LINK_M); | ||
439 | dev_priv->savePIPEB_DP_LINK_M = I915_READ(PIPEB_DP_LINK_M); | ||
440 | dev_priv->savePIPEA_DP_LINK_N = I915_READ(PIPEA_DP_LINK_N); | ||
441 | dev_priv->savePIPEB_DP_LINK_N = I915_READ(PIPEB_DP_LINK_N); | ||
442 | } | ||
325 | /* FIXME: save TV & SDVO state */ | 443 | /* FIXME: save TV & SDVO state */ |
326 | 444 | ||
327 | /* FBC state */ | 445 | /* FBC state */ |
@@ -404,92 +522,21 @@ int i915_restore_state(struct drm_device *dev) | |||
404 | for (i = 0; i < 8; i++) | 522 | for (i = 0; i < 8; i++) |
405 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | 523 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); |
406 | } | 524 | } |
407 | 525 | ||
408 | /* Pipe & plane A info */ | 526 | /* Display port ratios (must be done before clock is set) */ |
409 | /* Prime the clock */ | 527 | if (SUPPORTS_INTEGRATED_DP(dev)) { |
410 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 528 | I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); |
411 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | 529 | I915_WRITE(PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); |
412 | ~DPLL_VCO_ENABLE); | 530 | I915_WRITE(PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); |
413 | DRM_UDELAY(150); | 531 | I915_WRITE(PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); |
532 | I915_WRITE(PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); | ||
533 | I915_WRITE(PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); | ||
534 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); | ||
535 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); | ||
414 | } | 536 | } |
415 | I915_WRITE(FPA0, dev_priv->saveFPA0); | 537 | /* This is only meaningful in non-KMS mode */ |
416 | I915_WRITE(FPA1, dev_priv->saveFPA1); | 538 | /* Don't restore them in KMS mode */ |
417 | /* Actually enable it */ | 539 | i915_restore_modeset_reg(dev); |
418 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
419 | DRM_UDELAY(150); | ||
420 | if (IS_I965G(dev)) | ||
421 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
422 | DRM_UDELAY(150); | ||
423 | |||
424 | /* Restore mode */ | ||
425 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
426 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
427 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
428 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
429 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
430 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
431 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
432 | |||
433 | /* Restore plane info */ | ||
434 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
435 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
436 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
437 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
438 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
439 | if (IS_I965G(dev)) { | ||
440 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
441 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
442 | } | ||
443 | |||
444 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
445 | |||
446 | i915_restore_palette(dev, PIPE_A); | ||
447 | /* Enable the plane */ | ||
448 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
449 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
450 | |||
451 | /* Pipe & plane B info */ | ||
452 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
453 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
454 | ~DPLL_VCO_ENABLE); | ||
455 | DRM_UDELAY(150); | ||
456 | } | ||
457 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
458 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
459 | /* Actually enable it */ | ||
460 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
461 | DRM_UDELAY(150); | ||
462 | if (IS_I965G(dev)) | ||
463 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
464 | DRM_UDELAY(150); | ||
465 | |||
466 | /* Restore mode */ | ||
467 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
468 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
469 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
470 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
471 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
472 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
473 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
474 | |||
475 | /* Restore plane info */ | ||
476 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
477 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
478 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
479 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
480 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
481 | if (IS_I965G(dev)) { | ||
482 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
483 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
484 | } | ||
485 | |||
486 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
487 | |||
488 | i915_restore_palette(dev, PIPE_B); | ||
489 | /* Enable the plane */ | ||
490 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
491 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
492 | |||
493 | /* Cursor state */ | 540 | /* Cursor state */ |
494 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); | 541 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); |
495 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); | 542 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); |
@@ -518,6 +565,12 @@ int i915_restore_state(struct drm_device *dev) | |||
518 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); | 565 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); |
519 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); | 566 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); |
520 | 567 | ||
568 | /* Display Port state */ | ||
569 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
570 | I915_WRITE(DP_B, dev_priv->saveDP_B); | ||
571 | I915_WRITE(DP_C, dev_priv->saveDP_C); | ||
572 | I915_WRITE(DP_D, dev_priv->saveDP_D); | ||
573 | } | ||
521 | /* FIXME: restore TV & SDVO state */ | 574 | /* FIXME: restore TV & SDVO state */ |
522 | 575 | ||
523 | /* FBC info */ | 576 | /* FBC info */ |