Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: extract ums suspend/resume into i915_ums.c

Similarly to how i915_dma.c is shaping up to be the dungeon hole for
all things supporting dri1, create a new one to hide all the crazy
things which are only really useful for ums support. Biggest part is
the register suspend/resume support.

Unfortunately a lot of it is still intermingled with bits and pieces
we might still need, so needs more analysis and needs to stay in
i915_suspend.c for now.

Reviewed-by: Imre Deak <imre.deak@intel.com>

v2: s/modeset_reg/display_reg/ as suggested by Imre, to avoid
confusion between the kernel modeset code and display save/restore to
support ums.

v3: Fixup alphabetical order in the Makefile, spotted by Chris Wilson.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

+485 -452
+1
drivers/gpu/drm/i915/Makefile
··· 16 16 i915_gem_tiling.o \ 17 17 i915_sysfs.o \ 18 18 i915_trace_points.o \ 19 + i915_ums.o \ 19 20 intel_display.o \ 20 21 intel_crt.o \ 21 22 intel_lvds.o \
+3 -3
drivers/gpu/drm/i915/i915_drv.h
··· 1730 1730 extern int i915_save_state(struct drm_device *dev); 1731 1731 extern int i915_restore_state(struct drm_device *dev); 1732 1732 1733 - /* i915_suspend.c */ 1734 - extern int i915_save_state(struct drm_device *dev); 1735 - extern int i915_restore_state(struct drm_device *dev); 1733 + /* i915_ums.c */ 1734 + void i915_save_display_reg(struct drm_device *dev); 1735 + void i915_restore_display_reg(struct drm_device *dev); 1736 1736 1737 1737 /* i915_sysfs.c */ 1738 1738 void i915_setup_sysfs(struct drm_device *dev_priv);
+2 -449
drivers/gpu/drm/i915/i915_suspend.c
··· 29 29 #include "intel_drv.h" 30 30 #include "i915_reg.h" 31 31 32 - static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) 33 - { 34 - struct drm_i915_private *dev_priv = dev->dev_private; 35 - u32 dpll_reg; 36 - 37 - /* On IVB, 3rd pipe shares PLL with another one */ 38 - if (pipe > 1) 39 - return false; 40 - 41 - if (HAS_PCH_SPLIT(dev)) 42 - dpll_reg = _PCH_DPLL(pipe); 43 - else 44 - dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; 45 - 46 - return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE); 47 - } 48 - 49 - static void i915_save_palette(struct drm_device *dev, enum pipe pipe) 50 - { 51 - struct drm_i915_private *dev_priv = dev->dev_private; 52 - unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B); 53 - u32 *array; 54 - int i; 55 - 56 - if (!i915_pipe_enabled(dev, pipe)) 57 - return; 58 - 59 - if (HAS_PCH_SPLIT(dev)) 60 - reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B; 61 - 62 - if (pipe == PIPE_A) 63 - array = dev_priv->regfile.save_palette_a; 64 - else 65 - array = dev_priv->regfile.save_palette_b; 66 - 67 - for (i = 0; i < 256; i++) 68 - array[i] = I915_READ(reg + (i << 2)); 69 - } 70 - 71 - static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) 72 - { 73 - struct drm_i915_private *dev_priv = dev->dev_private; 74 - unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B); 75 - u32 *array; 76 - int i; 77 - 78 - if (!i915_pipe_enabled(dev, pipe)) 79 - return; 80 - 81 - if (HAS_PCH_SPLIT(dev)) 82 - reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B; 83 - 84 - if (pipe == PIPE_A) 85 - array = dev_priv->regfile.save_palette_a; 86 - else 87 - array = dev_priv->regfile.save_palette_b; 88 - 89 - for (i = 0; i < 256; i++) 90 - I915_WRITE(reg + (i << 2), array[i]); 91 - } 92 - 93 32 static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) 94 33 { 95 34 struct drm_i915_private *dev_priv = dev->dev_private; ··· 174 235 I915_WRITE8(VGA_DACMASK, dev_priv->regfile.saveDACMASK); 175 236 } 176 237 177 - static void i915_save_modeset_reg(struct drm_device *dev) 178 - { 179 - struct drm_i915_private *dev_priv = dev->dev_private; 180 - int i; 181 - 182 - /* Cursor state */ 183 - dev_priv->regfile.saveCURACNTR = I915_READ(_CURACNTR); 184 - dev_priv->regfile.saveCURAPOS = I915_READ(_CURAPOS); 185 - dev_priv->regfile.saveCURABASE = I915_READ(_CURABASE); 186 - dev_priv->regfile.saveCURBCNTR = I915_READ(_CURBCNTR); 187 - dev_priv->regfile.saveCURBPOS = I915_READ(_CURBPOS); 188 - dev_priv->regfile.saveCURBBASE = I915_READ(_CURBBASE); 189 - if (IS_GEN2(dev)) 190 - dev_priv->regfile.saveCURSIZE = I915_READ(CURSIZE); 191 - 192 - if (HAS_PCH_SPLIT(dev)) { 193 - dev_priv->regfile.savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); 194 - dev_priv->regfile.saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); 195 - } 196 - 197 - /* Pipe & plane A info */ 198 - dev_priv->regfile.savePIPEACONF = I915_READ(_PIPEACONF); 199 - dev_priv->regfile.savePIPEASRC = I915_READ(_PIPEASRC); 200 - if (HAS_PCH_SPLIT(dev)) { 201 - dev_priv->regfile.saveFPA0 = I915_READ(_PCH_FPA0); 202 - dev_priv->regfile.saveFPA1 = I915_READ(_PCH_FPA1); 203 - dev_priv->regfile.saveDPLL_A = I915_READ(_PCH_DPLL_A); 204 - } else { 205 - dev_priv->regfile.saveFPA0 = I915_READ(_FPA0); 206 - dev_priv->regfile.saveFPA1 = I915_READ(_FPA1); 207 - dev_priv->regfile.saveDPLL_A = I915_READ(_DPLL_A); 208 - } 209 - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) 210 - dev_priv->regfile.saveDPLL_A_MD = I915_READ(_DPLL_A_MD); 211 - dev_priv->regfile.saveHTOTAL_A = I915_READ(_HTOTAL_A); 212 - dev_priv->regfile.saveHBLANK_A = I915_READ(_HBLANK_A); 213 - dev_priv->regfile.saveHSYNC_A = I915_READ(_HSYNC_A); 214 - dev_priv->regfile.saveVTOTAL_A = I915_READ(_VTOTAL_A); 215 - dev_priv->regfile.saveVBLANK_A = I915_READ(_VBLANK_A); 216 - dev_priv->regfile.saveVSYNC_A = I915_READ(_VSYNC_A); 217 - if (!HAS_PCH_SPLIT(dev)) 218 - dev_priv->regfile.saveBCLRPAT_A = I915_READ(_BCLRPAT_A); 219 - 220 - if (HAS_PCH_SPLIT(dev)) { 221 - dev_priv->regfile.savePIPEA_DATA_M1 = I915_READ(_PIPEA_DATA_M1); 222 - dev_priv->regfile.savePIPEA_DATA_N1 = I915_READ(_PIPEA_DATA_N1); 223 - dev_priv->regfile.savePIPEA_LINK_M1 = I915_READ(_PIPEA_LINK_M1); 224 - dev_priv->regfile.savePIPEA_LINK_N1 = I915_READ(_PIPEA_LINK_N1); 225 - 226 - dev_priv->regfile.saveFDI_TXA_CTL = I915_READ(_FDI_TXA_CTL); 227 - dev_priv->regfile.saveFDI_RXA_CTL = I915_READ(_FDI_RXA_CTL); 228 - 229 - dev_priv->regfile.savePFA_CTL_1 = I915_READ(_PFA_CTL_1); 230 - dev_priv->regfile.savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ); 231 - dev_priv->regfile.savePFA_WIN_POS = I915_READ(_PFA_WIN_POS); 232 - 233 - dev_priv->regfile.saveTRANSACONF = I915_READ(_TRANSACONF); 234 - dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A); 235 - dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A); 236 - dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A); 237 - dev_priv->regfile.saveTRANS_VTOTAL_A = I915_READ(_TRANS_VTOTAL_A); 238 - dev_priv->regfile.saveTRANS_VBLANK_A = I915_READ(_TRANS_VBLANK_A); 239 - dev_priv->regfile.saveTRANS_VSYNC_A = I915_READ(_TRANS_VSYNC_A); 240 - } 241 - 242 - dev_priv->regfile.saveDSPACNTR = I915_READ(_DSPACNTR); 243 - dev_priv->regfile.saveDSPASTRIDE = I915_READ(_DSPASTRIDE); 244 - dev_priv->regfile.saveDSPASIZE = I915_READ(_DSPASIZE); 245 - dev_priv->regfile.saveDSPAPOS = I915_READ(_DSPAPOS); 246 - dev_priv->regfile.saveDSPAADDR = I915_READ(_DSPAADDR); 247 - if (INTEL_INFO(dev)->gen >= 4) { 248 - dev_priv->regfile.saveDSPASURF = I915_READ(_DSPASURF); 249 - dev_priv->regfile.saveDSPATILEOFF = I915_READ(_DSPATILEOFF); 250 - } 251 - i915_save_palette(dev, PIPE_A); 252 - dev_priv->regfile.savePIPEASTAT = I915_READ(_PIPEASTAT); 253 - 254 - /* Pipe & plane B info */ 255 - dev_priv->regfile.savePIPEBCONF = I915_READ(_PIPEBCONF); 256 - dev_priv->regfile.savePIPEBSRC = I915_READ(_PIPEBSRC); 257 - if (HAS_PCH_SPLIT(dev)) { 258 - dev_priv->regfile.saveFPB0 = I915_READ(_PCH_FPB0); 259 - dev_priv->regfile.saveFPB1 = I915_READ(_PCH_FPB1); 260 - dev_priv->regfile.saveDPLL_B = I915_READ(_PCH_DPLL_B); 261 - } else { 262 - dev_priv->regfile.saveFPB0 = I915_READ(_FPB0); 263 - dev_priv->regfile.saveFPB1 = I915_READ(_FPB1); 264 - dev_priv->regfile.saveDPLL_B = I915_READ(_DPLL_B); 265 - } 266 - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) 267 - dev_priv->regfile.saveDPLL_B_MD = I915_READ(_DPLL_B_MD); 268 - dev_priv->regfile.saveHTOTAL_B = I915_READ(_HTOTAL_B); 269 - dev_priv->regfile.saveHBLANK_B = I915_READ(_HBLANK_B); 270 - dev_priv->regfile.saveHSYNC_B = I915_READ(_HSYNC_B); 271 - dev_priv->regfile.saveVTOTAL_B = I915_READ(_VTOTAL_B); 272 - dev_priv->regfile.saveVBLANK_B = I915_READ(_VBLANK_B); 273 - dev_priv->regfile.saveVSYNC_B = I915_READ(_VSYNC_B); 274 - if (!HAS_PCH_SPLIT(dev)) 275 - dev_priv->regfile.saveBCLRPAT_B = I915_READ(_BCLRPAT_B); 276 - 277 - if (HAS_PCH_SPLIT(dev)) { 278 - dev_priv->regfile.savePIPEB_DATA_M1 = I915_READ(_PIPEB_DATA_M1); 279 - dev_priv->regfile.savePIPEB_DATA_N1 = I915_READ(_PIPEB_DATA_N1); 280 - dev_priv->regfile.savePIPEB_LINK_M1 = I915_READ(_PIPEB_LINK_M1); 281 - dev_priv->regfile.savePIPEB_LINK_N1 = I915_READ(_PIPEB_LINK_N1); 282 - 283 - dev_priv->regfile.saveFDI_TXB_CTL = I915_READ(_FDI_TXB_CTL); 284 - dev_priv->regfile.saveFDI_RXB_CTL = I915_READ(_FDI_RXB_CTL); 285 - 286 - dev_priv->regfile.savePFB_CTL_1 = I915_READ(_PFB_CTL_1); 287 - dev_priv->regfile.savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ); 288 - dev_priv->regfile.savePFB_WIN_POS = I915_READ(_PFB_WIN_POS); 289 - 290 - dev_priv->regfile.saveTRANSBCONF = I915_READ(_TRANSBCONF); 291 - dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B); 292 - dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B); 293 - dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B); 294 - dev_priv->regfile.saveTRANS_VTOTAL_B = I915_READ(_TRANS_VTOTAL_B); 295 - dev_priv->regfile.saveTRANS_VBLANK_B = I915_READ(_TRANS_VBLANK_B); 296 - dev_priv->regfile.saveTRANS_VSYNC_B = I915_READ(_TRANS_VSYNC_B); 297 - } 298 - 299 - dev_priv->regfile.saveDSPBCNTR = I915_READ(_DSPBCNTR); 300 - dev_priv->regfile.saveDSPBSTRIDE = I915_READ(_DSPBSTRIDE); 301 - dev_priv->regfile.saveDSPBSIZE = I915_READ(_DSPBSIZE); 302 - dev_priv->regfile.saveDSPBPOS = I915_READ(_DSPBPOS); 303 - dev_priv->regfile.saveDSPBADDR = I915_READ(_DSPBADDR); 304 - if (INTEL_INFO(dev)->gen >= 4) { 305 - dev_priv->regfile.saveDSPBSURF = I915_READ(_DSPBSURF); 306 - dev_priv->regfile.saveDSPBTILEOFF = I915_READ(_DSPBTILEOFF); 307 - } 308 - i915_save_palette(dev, PIPE_B); 309 - dev_priv->regfile.savePIPEBSTAT = I915_READ(_PIPEBSTAT); 310 - 311 - /* Fences */ 312 - switch (INTEL_INFO(dev)->gen) { 313 - case 7: 314 - case 6: 315 - for (i = 0; i < 16; i++) 316 - dev_priv->regfile.saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); 317 - break; 318 - case 5: 319 - case 4: 320 - for (i = 0; i < 16; i++) 321 - dev_priv->regfile.saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); 322 - break; 323 - case 3: 324 - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 325 - for (i = 0; i < 8; i++) 326 - dev_priv->regfile.saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); 327 - case 2: 328 - for (i = 0; i < 8; i++) 329 - dev_priv->regfile.saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); 330 - break; 331 - } 332 - 333 - /* CRT state */ 334 - if (HAS_PCH_SPLIT(dev)) 335 - dev_priv->regfile.saveADPA = I915_READ(PCH_ADPA); 336 - else 337 - dev_priv->regfile.saveADPA = I915_READ(ADPA); 338 - 339 - return; 340 - } 341 - 342 - static void i915_restore_modeset_reg(struct drm_device *dev) 343 - { 344 - struct drm_i915_private *dev_priv = dev->dev_private; 345 - int dpll_a_reg, fpa0_reg, fpa1_reg; 346 - int dpll_b_reg, fpb0_reg, fpb1_reg; 347 - int i; 348 - 349 - /* Display port ratios (must be done before clock is set) */ 350 - if (SUPPORTS_INTEGRATED_DP(dev)) { 351 - I915_WRITE(_PIPEA_GMCH_DATA_M, dev_priv->regfile.savePIPEA_GMCH_DATA_M); 352 - I915_WRITE(_PIPEB_GMCH_DATA_M, dev_priv->regfile.savePIPEB_GMCH_DATA_M); 353 - I915_WRITE(_PIPEA_GMCH_DATA_N, dev_priv->regfile.savePIPEA_GMCH_DATA_N); 354 - I915_WRITE(_PIPEB_GMCH_DATA_N, dev_priv->regfile.savePIPEB_GMCH_DATA_N); 355 - I915_WRITE(_PIPEA_DP_LINK_M, dev_priv->regfile.savePIPEA_DP_LINK_M); 356 - I915_WRITE(_PIPEB_DP_LINK_M, dev_priv->regfile.savePIPEB_DP_LINK_M); 357 - I915_WRITE(_PIPEA_DP_LINK_N, dev_priv->regfile.savePIPEA_DP_LINK_N); 358 - I915_WRITE(_PIPEB_DP_LINK_N, dev_priv->regfile.savePIPEB_DP_LINK_N); 359 - } 360 - 361 - /* Fences */ 362 - switch (INTEL_INFO(dev)->gen) { 363 - case 7: 364 - case 6: 365 - for (i = 0; i < 16; i++) 366 - I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->regfile.saveFENCE[i]); 367 - break; 368 - case 5: 369 - case 4: 370 - for (i = 0; i < 16; i++) 371 - I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->regfile.saveFENCE[i]); 372 - break; 373 - case 3: 374 - case 2: 375 - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 376 - for (i = 0; i < 8; i++) 377 - I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->regfile.saveFENCE[i+8]); 378 - for (i = 0; i < 8; i++) 379 - I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->regfile.saveFENCE[i]); 380 - break; 381 - } 382 - 383 - 384 - if (HAS_PCH_SPLIT(dev)) { 385 - dpll_a_reg = _PCH_DPLL_A; 386 - dpll_b_reg = _PCH_DPLL_B; 387 - fpa0_reg = _PCH_FPA0; 388 - fpb0_reg = _PCH_FPB0; 389 - fpa1_reg = _PCH_FPA1; 390 - fpb1_reg = _PCH_FPB1; 391 - } else { 392 - dpll_a_reg = _DPLL_A; 393 - dpll_b_reg = _DPLL_B; 394 - fpa0_reg = _FPA0; 395 - fpb0_reg = _FPB0; 396 - fpa1_reg = _FPA1; 397 - fpb1_reg = _FPB1; 398 - } 399 - 400 - if (HAS_PCH_SPLIT(dev)) { 401 - I915_WRITE(PCH_DREF_CONTROL, dev_priv->regfile.savePCH_DREF_CONTROL); 402 - I915_WRITE(DISP_ARB_CTL, dev_priv->regfile.saveDISP_ARB_CTL); 403 - } 404 - 405 - /* Pipe & plane A info */ 406 - /* Prime the clock */ 407 - if (dev_priv->regfile.saveDPLL_A & DPLL_VCO_ENABLE) { 408 - I915_WRITE(dpll_a_reg, dev_priv->regfile.saveDPLL_A & 409 - ~DPLL_VCO_ENABLE); 410 - POSTING_READ(dpll_a_reg); 411 - udelay(150); 412 - } 413 - I915_WRITE(fpa0_reg, dev_priv->regfile.saveFPA0); 414 - I915_WRITE(fpa1_reg, dev_priv->regfile.saveFPA1); 415 - /* Actually enable it */ 416 - I915_WRITE(dpll_a_reg, dev_priv->regfile.saveDPLL_A); 417 - POSTING_READ(dpll_a_reg); 418 - udelay(150); 419 - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { 420 - I915_WRITE(_DPLL_A_MD, dev_priv->regfile.saveDPLL_A_MD); 421 - POSTING_READ(_DPLL_A_MD); 422 - } 423 - udelay(150); 424 - 425 - /* Restore mode */ 426 - I915_WRITE(_HTOTAL_A, dev_priv->regfile.saveHTOTAL_A); 427 - I915_WRITE(_HBLANK_A, dev_priv->regfile.saveHBLANK_A); 428 - I915_WRITE(_HSYNC_A, dev_priv->regfile.saveHSYNC_A); 429 - I915_WRITE(_VTOTAL_A, dev_priv->regfile.saveVTOTAL_A); 430 - I915_WRITE(_VBLANK_A, dev_priv->regfile.saveVBLANK_A); 431 - I915_WRITE(_VSYNC_A, dev_priv->regfile.saveVSYNC_A); 432 - if (!HAS_PCH_SPLIT(dev)) 433 - I915_WRITE(_BCLRPAT_A, dev_priv->regfile.saveBCLRPAT_A); 434 - 435 - if (HAS_PCH_SPLIT(dev)) { 436 - I915_WRITE(_PIPEA_DATA_M1, dev_priv->regfile.savePIPEA_DATA_M1); 437 - I915_WRITE(_PIPEA_DATA_N1, dev_priv->regfile.savePIPEA_DATA_N1); 438 - I915_WRITE(_PIPEA_LINK_M1, dev_priv->regfile.savePIPEA_LINK_M1); 439 - I915_WRITE(_PIPEA_LINK_N1, dev_priv->regfile.savePIPEA_LINK_N1); 440 - 441 - I915_WRITE(_FDI_RXA_CTL, dev_priv->regfile.saveFDI_RXA_CTL); 442 - I915_WRITE(_FDI_TXA_CTL, dev_priv->regfile.saveFDI_TXA_CTL); 443 - 444 - I915_WRITE(_PFA_CTL_1, dev_priv->regfile.savePFA_CTL_1); 445 - I915_WRITE(_PFA_WIN_SZ, dev_priv->regfile.savePFA_WIN_SZ); 446 - I915_WRITE(_PFA_WIN_POS, dev_priv->regfile.savePFA_WIN_POS); 447 - 448 - I915_WRITE(_TRANSACONF, dev_priv->regfile.saveTRANSACONF); 449 - I915_WRITE(_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A); 450 - I915_WRITE(_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A); 451 - I915_WRITE(_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A); 452 - I915_WRITE(_TRANS_VTOTAL_A, dev_priv->regfile.saveTRANS_VTOTAL_A); 453 - I915_WRITE(_TRANS_VBLANK_A, dev_priv->regfile.saveTRANS_VBLANK_A); 454 - I915_WRITE(_TRANS_VSYNC_A, dev_priv->regfile.saveTRANS_VSYNC_A); 455 - } 456 - 457 - /* Restore plane info */ 458 - I915_WRITE(_DSPASIZE, dev_priv->regfile.saveDSPASIZE); 459 - I915_WRITE(_DSPAPOS, dev_priv->regfile.saveDSPAPOS); 460 - I915_WRITE(_PIPEASRC, dev_priv->regfile.savePIPEASRC); 461 - I915_WRITE(_DSPAADDR, dev_priv->regfile.saveDSPAADDR); 462 - I915_WRITE(_DSPASTRIDE, dev_priv->regfile.saveDSPASTRIDE); 463 - if (INTEL_INFO(dev)->gen >= 4) { 464 - I915_WRITE(_DSPASURF, dev_priv->regfile.saveDSPASURF); 465 - I915_WRITE(_DSPATILEOFF, dev_priv->regfile.saveDSPATILEOFF); 466 - } 467 - 468 - I915_WRITE(_PIPEACONF, dev_priv->regfile.savePIPEACONF); 469 - 470 - i915_restore_palette(dev, PIPE_A); 471 - /* Enable the plane */ 472 - I915_WRITE(_DSPACNTR, dev_priv->regfile.saveDSPACNTR); 473 - I915_WRITE(_DSPAADDR, I915_READ(_DSPAADDR)); 474 - 475 - /* Pipe & plane B info */ 476 - if (dev_priv->regfile.saveDPLL_B & DPLL_VCO_ENABLE) { 477 - I915_WRITE(dpll_b_reg, dev_priv->regfile.saveDPLL_B & 478 - ~DPLL_VCO_ENABLE); 479 - POSTING_READ(dpll_b_reg); 480 - udelay(150); 481 - } 482 - I915_WRITE(fpb0_reg, dev_priv->regfile.saveFPB0); 483 - I915_WRITE(fpb1_reg, dev_priv->regfile.saveFPB1); 484 - /* Actually enable it */ 485 - I915_WRITE(dpll_b_reg, dev_priv->regfile.saveDPLL_B); 486 - POSTING_READ(dpll_b_reg); 487 - udelay(150); 488 - if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { 489 - I915_WRITE(_DPLL_B_MD, dev_priv->regfile.saveDPLL_B_MD); 490 - POSTING_READ(_DPLL_B_MD); 491 - } 492 - udelay(150); 493 - 494 - /* Restore mode */ 495 - I915_WRITE(_HTOTAL_B, dev_priv->regfile.saveHTOTAL_B); 496 - I915_WRITE(_HBLANK_B, dev_priv->regfile.saveHBLANK_B); 497 - I915_WRITE(_HSYNC_B, dev_priv->regfile.saveHSYNC_B); 498 - I915_WRITE(_VTOTAL_B, dev_priv->regfile.saveVTOTAL_B); 499 - I915_WRITE(_VBLANK_B, dev_priv->regfile.saveVBLANK_B); 500 - I915_WRITE(_VSYNC_B, dev_priv->regfile.saveVSYNC_B); 501 - if (!HAS_PCH_SPLIT(dev)) 502 - I915_WRITE(_BCLRPAT_B, dev_priv->regfile.saveBCLRPAT_B); 503 - 504 - if (HAS_PCH_SPLIT(dev)) { 505 - I915_WRITE(_PIPEB_DATA_M1, dev_priv->regfile.savePIPEB_DATA_M1); 506 - I915_WRITE(_PIPEB_DATA_N1, dev_priv->regfile.savePIPEB_DATA_N1); 507 - I915_WRITE(_PIPEB_LINK_M1, dev_priv->regfile.savePIPEB_LINK_M1); 508 - I915_WRITE(_PIPEB_LINK_N1, dev_priv->regfile.savePIPEB_LINK_N1); 509 - 510 - I915_WRITE(_FDI_RXB_CTL, dev_priv->regfile.saveFDI_RXB_CTL); 511 - I915_WRITE(_FDI_TXB_CTL, dev_priv->regfile.saveFDI_TXB_CTL); 512 - 513 - I915_WRITE(_PFB_CTL_1, dev_priv->regfile.savePFB_CTL_1); 514 - I915_WRITE(_PFB_WIN_SZ, dev_priv->regfile.savePFB_WIN_SZ); 515 - I915_WRITE(_PFB_WIN_POS, dev_priv->regfile.savePFB_WIN_POS); 516 - 517 - I915_WRITE(_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF); 518 - I915_WRITE(_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B); 519 - I915_WRITE(_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B); 520 - I915_WRITE(_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B); 521 - I915_WRITE(_TRANS_VTOTAL_B, dev_priv->regfile.saveTRANS_VTOTAL_B); 522 - I915_WRITE(_TRANS_VBLANK_B, dev_priv->regfile.saveTRANS_VBLANK_B); 523 - I915_WRITE(_TRANS_VSYNC_B, dev_priv->regfile.saveTRANS_VSYNC_B); 524 - } 525 - 526 - /* Restore plane info */ 527 - I915_WRITE(_DSPBSIZE, dev_priv->regfile.saveDSPBSIZE); 528 - I915_WRITE(_DSPBPOS, dev_priv->regfile.saveDSPBPOS); 529 - I915_WRITE(_PIPEBSRC, dev_priv->regfile.savePIPEBSRC); 530 - I915_WRITE(_DSPBADDR, dev_priv->regfile.saveDSPBADDR); 531 - I915_WRITE(_DSPBSTRIDE, dev_priv->regfile.saveDSPBSTRIDE); 532 - if (INTEL_INFO(dev)->gen >= 4) { 533 - I915_WRITE(_DSPBSURF, dev_priv->regfile.saveDSPBSURF); 534 - I915_WRITE(_DSPBTILEOFF, dev_priv->regfile.saveDSPBTILEOFF); 535 - } 536 - 537 - I915_WRITE(_PIPEBCONF, dev_priv->regfile.savePIPEBCONF); 538 - 539 - i915_restore_palette(dev, PIPE_B); 540 - /* Enable the plane */ 541 - I915_WRITE(_DSPBCNTR, dev_priv->regfile.saveDSPBCNTR); 542 - I915_WRITE(_DSPBADDR, I915_READ(_DSPBADDR)); 543 - 544 - /* Cursor state */ 545 - I915_WRITE(_CURAPOS, dev_priv->regfile.saveCURAPOS); 546 - I915_WRITE(_CURACNTR, dev_priv->regfile.saveCURACNTR); 547 - I915_WRITE(_CURABASE, dev_priv->regfile.saveCURABASE); 548 - I915_WRITE(_CURBPOS, dev_priv->regfile.saveCURBPOS); 549 - I915_WRITE(_CURBCNTR, dev_priv->regfile.saveCURBCNTR); 550 - I915_WRITE(_CURBBASE, dev_priv->regfile.saveCURBBASE); 551 - if (IS_GEN2(dev)) 552 - I915_WRITE(CURSIZE, dev_priv->regfile.saveCURSIZE); 553 - 554 - /* CRT state */ 555 - if (HAS_PCH_SPLIT(dev)) 556 - I915_WRITE(PCH_ADPA, dev_priv->regfile.saveADPA); 557 - else 558 - I915_WRITE(ADPA, dev_priv->regfile.saveADPA); 559 - 560 - return; 561 - } 562 - 563 238 static void i915_save_display(struct drm_device *dev) 564 239 { 565 240 struct drm_i915_private *dev_priv = dev->dev_private; ··· 185 632 /* This is only meaningful in non-KMS mode */ 186 633 /* Don't regfile.save them in KMS mode */ 187 634 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 188 - i915_save_modeset_reg(dev); 635 + i915_save_display_reg(dev); 189 636 190 637 /* LVDS state */ 191 638 if (HAS_PCH_SPLIT(dev)) { ··· 272 719 I915_WRITE(DSPARB, dev_priv->regfile.saveDSPARB); 273 720 274 721 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 275 - i915_restore_modeset_reg(dev); 722 + i915_restore_display_reg(dev); 276 723 277 724 /* LVDS state */ 278 725 if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
+479
drivers/gpu/drm/i915/i915_ums.c
··· 1 + /* 2 + * 3 + * Copyright 2008 (c) Intel Corporation 4 + * Jesse Barnes <jbarnes@virtuousgeek.org> 5 + * Copyright 2013 (c) Intel Corporation 6 + * Daniel Vetter <daniel.vetter@ffwll.ch> 7 + * 8 + * Permission is hereby granted, free of charge, to any person obtaining a 9 + * copy of this software and associated documentation files (the 10 + * "Software"), to deal in the Software without restriction, including 11 + * without limitation the rights to use, copy, modify, merge, publish, 12 + * distribute, sub license, and/or sell copies of the Software, and to 13 + * permit persons to whom the Software is furnished to do so, subject to 14 + * the following conditions: 15 + * 16 + * The above copyright notice and this permission notice (including the 17 + * next paragraph) shall be included in all copies or substantial portions 18 + * of the Software. 19 + * 20 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 23 + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 24 + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26 + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 + */ 28 + 29 + #include <drm/drmP.h> 30 + #include <drm/i915_drm.h> 31 + #include "intel_drv.h" 32 + #include "i915_reg.h" 33 + 34 + static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) 35 + { 36 + struct drm_i915_private *dev_priv = dev->dev_private; 37 + u32 dpll_reg; 38 + 39 + /* On IVB, 3rd pipe shares PLL with another one */ 40 + if (pipe > 1) 41 + return false; 42 + 43 + if (HAS_PCH_SPLIT(dev)) 44 + dpll_reg = _PCH_DPLL(pipe); 45 + else 46 + dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; 47 + 48 + return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE); 49 + } 50 + 51 + static void i915_save_palette(struct drm_device *dev, enum pipe pipe) 52 + { 53 + struct drm_i915_private *dev_priv = dev->dev_private; 54 + unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B); 55 + u32 *array; 56 + int i; 57 + 58 + if (!i915_pipe_enabled(dev, pipe)) 59 + return; 60 + 61 + if (HAS_PCH_SPLIT(dev)) 62 + reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B; 63 + 64 + if (pipe == PIPE_A) 65 + array = dev_priv->regfile.save_palette_a; 66 + else 67 + array = dev_priv->regfile.save_palette_b; 68 + 69 + for (i = 0; i < 256; i++) 70 + array[i] = I915_READ(reg + (i << 2)); 71 + } 72 + 73 + static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) 74 + { 75 + struct drm_i915_private *dev_priv = dev->dev_private; 76 + unsigned long reg = (pipe == PIPE_A ? _PALETTE_A : _PALETTE_B); 77 + u32 *array; 78 + int i; 79 + 80 + if (!i915_pipe_enabled(dev, pipe)) 81 + return; 82 + 83 + if (HAS_PCH_SPLIT(dev)) 84 + reg = (pipe == PIPE_A) ? _LGC_PALETTE_A : _LGC_PALETTE_B; 85 + 86 + if (pipe == PIPE_A) 87 + array = dev_priv->regfile.save_palette_a; 88 + else 89 + array = dev_priv->regfile.save_palette_b; 90 + 91 + for (i = 0; i < 256; i++) 92 + I915_WRITE(reg + (i << 2), array[i]); 93 + } 94 + 95 + void i915_save_display_reg(struct drm_device *dev) 96 + { 97 + struct drm_i915_private *dev_priv = dev->dev_private; 98 + int i; 99 + 100 + /* Cursor state */ 101 + dev_priv->regfile.saveCURACNTR = I915_READ(_CURACNTR); 102 + dev_priv->regfile.saveCURAPOS = I915_READ(_CURAPOS); 103 + dev_priv->regfile.saveCURABASE = I915_READ(_CURABASE); 104 + dev_priv->regfile.saveCURBCNTR = I915_READ(_CURBCNTR); 105 + dev_priv->regfile.saveCURBPOS = I915_READ(_CURBPOS); 106 + dev_priv->regfile.saveCURBBASE = I915_READ(_CURBBASE); 107 + if (IS_GEN2(dev)) 108 + dev_priv->regfile.saveCURSIZE = I915_READ(CURSIZE); 109 + 110 + if (HAS_PCH_SPLIT(dev)) { 111 + dev_priv->regfile.savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); 112 + dev_priv->regfile.saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); 113 + } 114 + 115 + /* Pipe & plane A info */ 116 + dev_priv->regfile.savePIPEACONF = I915_READ(_PIPEACONF); 117 + dev_priv->regfile.savePIPEASRC = I915_READ(_PIPEASRC); 118 + if (HAS_PCH_SPLIT(dev)) { 119 + dev_priv->regfile.saveFPA0 = I915_READ(_PCH_FPA0); 120 + dev_priv->regfile.saveFPA1 = I915_READ(_PCH_FPA1); 121 + dev_priv->regfile.saveDPLL_A = I915_READ(_PCH_DPLL_A); 122 + } else { 123 + dev_priv->regfile.saveFPA0 = I915_READ(_FPA0); 124 + dev_priv->regfile.saveFPA1 = I915_READ(_FPA1); 125 + dev_priv->regfile.saveDPLL_A = I915_READ(_DPLL_A); 126 + } 127 + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) 128 + dev_priv->regfile.saveDPLL_A_MD = I915_READ(_DPLL_A_MD); 129 + dev_priv->regfile.saveHTOTAL_A = I915_READ(_HTOTAL_A); 130 + dev_priv->regfile.saveHBLANK_A = I915_READ(_HBLANK_A); 131 + dev_priv->regfile.saveHSYNC_A = I915_READ(_HSYNC_A); 132 + dev_priv->regfile.saveVTOTAL_A = I915_READ(_VTOTAL_A); 133 + dev_priv->regfile.saveVBLANK_A = I915_READ(_VBLANK_A); 134 + dev_priv->regfile.saveVSYNC_A = I915_READ(_VSYNC_A); 135 + if (!HAS_PCH_SPLIT(dev)) 136 + dev_priv->regfile.saveBCLRPAT_A = I915_READ(_BCLRPAT_A); 137 + 138 + if (HAS_PCH_SPLIT(dev)) { 139 + dev_priv->regfile.savePIPEA_DATA_M1 = I915_READ(_PIPEA_DATA_M1); 140 + dev_priv->regfile.savePIPEA_DATA_N1 = I915_READ(_PIPEA_DATA_N1); 141 + dev_priv->regfile.savePIPEA_LINK_M1 = I915_READ(_PIPEA_LINK_M1); 142 + dev_priv->regfile.savePIPEA_LINK_N1 = I915_READ(_PIPEA_LINK_N1); 143 + 144 + dev_priv->regfile.saveFDI_TXA_CTL = I915_READ(_FDI_TXA_CTL); 145 + dev_priv->regfile.saveFDI_RXA_CTL = I915_READ(_FDI_RXA_CTL); 146 + 147 + dev_priv->regfile.savePFA_CTL_1 = I915_READ(_PFA_CTL_1); 148 + dev_priv->regfile.savePFA_WIN_SZ = I915_READ(_PFA_WIN_SZ); 149 + dev_priv->regfile.savePFA_WIN_POS = I915_READ(_PFA_WIN_POS); 150 + 151 + dev_priv->regfile.saveTRANSACONF = I915_READ(_TRANSACONF); 152 + dev_priv->regfile.saveTRANS_HTOTAL_A = I915_READ(_TRANS_HTOTAL_A); 153 + dev_priv->regfile.saveTRANS_HBLANK_A = I915_READ(_TRANS_HBLANK_A); 154 + dev_priv->regfile.saveTRANS_HSYNC_A = I915_READ(_TRANS_HSYNC_A); 155 + dev_priv->regfile.saveTRANS_VTOTAL_A = I915_READ(_TRANS_VTOTAL_A); 156 + dev_priv->regfile.saveTRANS_VBLANK_A = I915_READ(_TRANS_VBLANK_A); 157 + dev_priv->regfile.saveTRANS_VSYNC_A = I915_READ(_TRANS_VSYNC_A); 158 + } 159 + 160 + dev_priv->regfile.saveDSPACNTR = I915_READ(_DSPACNTR); 161 + dev_priv->regfile.saveDSPASTRIDE = I915_READ(_DSPASTRIDE); 162 + dev_priv->regfile.saveDSPASIZE = I915_READ(_DSPASIZE); 163 + dev_priv->regfile.saveDSPAPOS = I915_READ(_DSPAPOS); 164 + dev_priv->regfile.saveDSPAADDR = I915_READ(_DSPAADDR); 165 + if (INTEL_INFO(dev)->gen >= 4) { 166 + dev_priv->regfile.saveDSPASURF = I915_READ(_DSPASURF); 167 + dev_priv->regfile.saveDSPATILEOFF = I915_READ(_DSPATILEOFF); 168 + } 169 + i915_save_palette(dev, PIPE_A); 170 + dev_priv->regfile.savePIPEASTAT = I915_READ(_PIPEASTAT); 171 + 172 + /* Pipe & plane B info */ 173 + dev_priv->regfile.savePIPEBCONF = I915_READ(_PIPEBCONF); 174 + dev_priv->regfile.savePIPEBSRC = I915_READ(_PIPEBSRC); 175 + if (HAS_PCH_SPLIT(dev)) { 176 + dev_priv->regfile.saveFPB0 = I915_READ(_PCH_FPB0); 177 + dev_priv->regfile.saveFPB1 = I915_READ(_PCH_FPB1); 178 + dev_priv->regfile.saveDPLL_B = I915_READ(_PCH_DPLL_B); 179 + } else { 180 + dev_priv->regfile.saveFPB0 = I915_READ(_FPB0); 181 + dev_priv->regfile.saveFPB1 = I915_READ(_FPB1); 182 + dev_priv->regfile.saveDPLL_B = I915_READ(_DPLL_B); 183 + } 184 + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) 185 + dev_priv->regfile.saveDPLL_B_MD = I915_READ(_DPLL_B_MD); 186 + dev_priv->regfile.saveHTOTAL_B = I915_READ(_HTOTAL_B); 187 + dev_priv->regfile.saveHBLANK_B = I915_READ(_HBLANK_B); 188 + dev_priv->regfile.saveHSYNC_B = I915_READ(_HSYNC_B); 189 + dev_priv->regfile.saveVTOTAL_B = I915_READ(_VTOTAL_B); 190 + dev_priv->regfile.saveVBLANK_B = I915_READ(_VBLANK_B); 191 + dev_priv->regfile.saveVSYNC_B = I915_READ(_VSYNC_B); 192 + if (!HAS_PCH_SPLIT(dev)) 193 + dev_priv->regfile.saveBCLRPAT_B = I915_READ(_BCLRPAT_B); 194 + 195 + if (HAS_PCH_SPLIT(dev)) { 196 + dev_priv->regfile.savePIPEB_DATA_M1 = I915_READ(_PIPEB_DATA_M1); 197 + dev_priv->regfile.savePIPEB_DATA_N1 = I915_READ(_PIPEB_DATA_N1); 198 + dev_priv->regfile.savePIPEB_LINK_M1 = I915_READ(_PIPEB_LINK_M1); 199 + dev_priv->regfile.savePIPEB_LINK_N1 = I915_READ(_PIPEB_LINK_N1); 200 + 201 + dev_priv->regfile.saveFDI_TXB_CTL = I915_READ(_FDI_TXB_CTL); 202 + dev_priv->regfile.saveFDI_RXB_CTL = I915_READ(_FDI_RXB_CTL); 203 + 204 + dev_priv->regfile.savePFB_CTL_1 = I915_READ(_PFB_CTL_1); 205 + dev_priv->regfile.savePFB_WIN_SZ = I915_READ(_PFB_WIN_SZ); 206 + dev_priv->regfile.savePFB_WIN_POS = I915_READ(_PFB_WIN_POS); 207 + 208 + dev_priv->regfile.saveTRANSBCONF = I915_READ(_TRANSBCONF); 209 + dev_priv->regfile.saveTRANS_HTOTAL_B = I915_READ(_TRANS_HTOTAL_B); 210 + dev_priv->regfile.saveTRANS_HBLANK_B = I915_READ(_TRANS_HBLANK_B); 211 + dev_priv->regfile.saveTRANS_HSYNC_B = I915_READ(_TRANS_HSYNC_B); 212 + dev_priv->regfile.saveTRANS_VTOTAL_B = I915_READ(_TRANS_VTOTAL_B); 213 + dev_priv->regfile.saveTRANS_VBLANK_B = I915_READ(_TRANS_VBLANK_B); 214 + dev_priv->regfile.saveTRANS_VSYNC_B = I915_READ(_TRANS_VSYNC_B); 215 + } 216 + 217 + dev_priv->regfile.saveDSPBCNTR = I915_READ(_DSPBCNTR); 218 + dev_priv->regfile.saveDSPBSTRIDE = I915_READ(_DSPBSTRIDE); 219 + dev_priv->regfile.saveDSPBSIZE = I915_READ(_DSPBSIZE); 220 + dev_priv->regfile.saveDSPBPOS = I915_READ(_DSPBPOS); 221 + dev_priv->regfile.saveDSPBADDR = I915_READ(_DSPBADDR); 222 + if (INTEL_INFO(dev)->gen >= 4) { 223 + dev_priv->regfile.saveDSPBSURF = I915_READ(_DSPBSURF); 224 + dev_priv->regfile.saveDSPBTILEOFF = I915_READ(_DSPBTILEOFF); 225 + } 226 + i915_save_palette(dev, PIPE_B); 227 + dev_priv->regfile.savePIPEBSTAT = I915_READ(_PIPEBSTAT); 228 + 229 + /* Fences */ 230 + switch (INTEL_INFO(dev)->gen) { 231 + case 7: 232 + case 6: 233 + for (i = 0; i < 16; i++) 234 + dev_priv->regfile.saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); 235 + break; 236 + case 5: 237 + case 4: 238 + for (i = 0; i < 16; i++) 239 + dev_priv->regfile.saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); 240 + break; 241 + case 3: 242 + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 243 + for (i = 0; i < 8; i++) 244 + dev_priv->regfile.saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); 245 + case 2: 246 + for (i = 0; i < 8; i++) 247 + dev_priv->regfile.saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); 248 + break; 249 + } 250 + 251 + /* CRT state */ 252 + if (HAS_PCH_SPLIT(dev)) 253 + dev_priv->regfile.saveADPA = I915_READ(PCH_ADPA); 254 + else 255 + dev_priv->regfile.saveADPA = I915_READ(ADPA); 256 + 257 + return; 258 + } 259 + 260 + void i915_restore_display_reg(struct drm_device *dev) 261 + { 262 + struct drm_i915_private *dev_priv = dev->dev_private; 263 + int dpll_a_reg, fpa0_reg, fpa1_reg; 264 + int dpll_b_reg, fpb0_reg, fpb1_reg; 265 + int i; 266 + 267 + /* Display port ratios (must be done before clock is set) */ 268 + if (SUPPORTS_INTEGRATED_DP(dev)) { 269 + I915_WRITE(_PIPEA_GMCH_DATA_M, dev_priv->regfile.savePIPEA_GMCH_DATA_M); 270 + I915_WRITE(_PIPEB_GMCH_DATA_M, dev_priv->regfile.savePIPEB_GMCH_DATA_M); 271 + I915_WRITE(_PIPEA_GMCH_DATA_N, dev_priv->regfile.savePIPEA_GMCH_DATA_N); 272 + I915_WRITE(_PIPEB_GMCH_DATA_N, dev_priv->regfile.savePIPEB_GMCH_DATA_N); 273 + I915_WRITE(_PIPEA_DP_LINK_M, dev_priv->regfile.savePIPEA_DP_LINK_M); 274 + I915_WRITE(_PIPEB_DP_LINK_M, dev_priv->regfile.savePIPEB_DP_LINK_M); 275 + I915_WRITE(_PIPEA_DP_LINK_N, dev_priv->regfile.savePIPEA_DP_LINK_N); 276 + I915_WRITE(_PIPEB_DP_LINK_N, dev_priv->regfile.savePIPEB_DP_LINK_N); 277 + } 278 + 279 + /* Fences */ 280 + switch (INTEL_INFO(dev)->gen) { 281 + case 7: 282 + case 6: 283 + for (i = 0; i < 16; i++) 284 + I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->regfile.saveFENCE[i]); 285 + break; 286 + case 5: 287 + case 4: 288 + for (i = 0; i < 16; i++) 289 + I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->regfile.saveFENCE[i]); 290 + break; 291 + case 3: 292 + case 2: 293 + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 294 + for (i = 0; i < 8; i++) 295 + I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->regfile.saveFENCE[i+8]); 296 + for (i = 0; i < 8; i++) 297 + I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->regfile.saveFENCE[i]); 298 + break; 299 + } 300 + 301 + 302 + if (HAS_PCH_SPLIT(dev)) { 303 + dpll_a_reg = _PCH_DPLL_A; 304 + dpll_b_reg = _PCH_DPLL_B; 305 + fpa0_reg = _PCH_FPA0; 306 + fpb0_reg = _PCH_FPB0; 307 + fpa1_reg = _PCH_FPA1; 308 + fpb1_reg = _PCH_FPB1; 309 + } else { 310 + dpll_a_reg = _DPLL_A; 311 + dpll_b_reg = _DPLL_B; 312 + fpa0_reg = _FPA0; 313 + fpb0_reg = _FPB0; 314 + fpa1_reg = _FPA1; 315 + fpb1_reg = _FPB1; 316 + } 317 + 318 + if (HAS_PCH_SPLIT(dev)) { 319 + I915_WRITE(PCH_DREF_CONTROL, dev_priv->regfile.savePCH_DREF_CONTROL); 320 + I915_WRITE(DISP_ARB_CTL, dev_priv->regfile.saveDISP_ARB_CTL); 321 + } 322 + 323 + /* Pipe & plane A info */ 324 + /* Prime the clock */ 325 + if (dev_priv->regfile.saveDPLL_A & DPLL_VCO_ENABLE) { 326 + I915_WRITE(dpll_a_reg, dev_priv->regfile.saveDPLL_A & 327 + ~DPLL_VCO_ENABLE); 328 + POSTING_READ(dpll_a_reg); 329 + udelay(150); 330 + } 331 + I915_WRITE(fpa0_reg, dev_priv->regfile.saveFPA0); 332 + I915_WRITE(fpa1_reg, dev_priv->regfile.saveFPA1); 333 + /* Actually enable it */ 334 + I915_WRITE(dpll_a_reg, dev_priv->regfile.saveDPLL_A); 335 + POSTING_READ(dpll_a_reg); 336 + udelay(150); 337 + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { 338 + I915_WRITE(_DPLL_A_MD, dev_priv->regfile.saveDPLL_A_MD); 339 + POSTING_READ(_DPLL_A_MD); 340 + } 341 + udelay(150); 342 + 343 + /* Restore mode */ 344 + I915_WRITE(_HTOTAL_A, dev_priv->regfile.saveHTOTAL_A); 345 + I915_WRITE(_HBLANK_A, dev_priv->regfile.saveHBLANK_A); 346 + I915_WRITE(_HSYNC_A, dev_priv->regfile.saveHSYNC_A); 347 + I915_WRITE(_VTOTAL_A, dev_priv->regfile.saveVTOTAL_A); 348 + I915_WRITE(_VBLANK_A, dev_priv->regfile.saveVBLANK_A); 349 + I915_WRITE(_VSYNC_A, dev_priv->regfile.saveVSYNC_A); 350 + if (!HAS_PCH_SPLIT(dev)) 351 + I915_WRITE(_BCLRPAT_A, dev_priv->regfile.saveBCLRPAT_A); 352 + 353 + if (HAS_PCH_SPLIT(dev)) { 354 + I915_WRITE(_PIPEA_DATA_M1, dev_priv->regfile.savePIPEA_DATA_M1); 355 + I915_WRITE(_PIPEA_DATA_N1, dev_priv->regfile.savePIPEA_DATA_N1); 356 + I915_WRITE(_PIPEA_LINK_M1, dev_priv->regfile.savePIPEA_LINK_M1); 357 + I915_WRITE(_PIPEA_LINK_N1, dev_priv->regfile.savePIPEA_LINK_N1); 358 + 359 + I915_WRITE(_FDI_RXA_CTL, dev_priv->regfile.saveFDI_RXA_CTL); 360 + I915_WRITE(_FDI_TXA_CTL, dev_priv->regfile.saveFDI_TXA_CTL); 361 + 362 + I915_WRITE(_PFA_CTL_1, dev_priv->regfile.savePFA_CTL_1); 363 + I915_WRITE(_PFA_WIN_SZ, dev_priv->regfile.savePFA_WIN_SZ); 364 + I915_WRITE(_PFA_WIN_POS, dev_priv->regfile.savePFA_WIN_POS); 365 + 366 + I915_WRITE(_TRANSACONF, dev_priv->regfile.saveTRANSACONF); 367 + I915_WRITE(_TRANS_HTOTAL_A, dev_priv->regfile.saveTRANS_HTOTAL_A); 368 + I915_WRITE(_TRANS_HBLANK_A, dev_priv->regfile.saveTRANS_HBLANK_A); 369 + I915_WRITE(_TRANS_HSYNC_A, dev_priv->regfile.saveTRANS_HSYNC_A); 370 + I915_WRITE(_TRANS_VTOTAL_A, dev_priv->regfile.saveTRANS_VTOTAL_A); 371 + I915_WRITE(_TRANS_VBLANK_A, dev_priv->regfile.saveTRANS_VBLANK_A); 372 + I915_WRITE(_TRANS_VSYNC_A, dev_priv->regfile.saveTRANS_VSYNC_A); 373 + } 374 + 375 + /* Restore plane info */ 376 + I915_WRITE(_DSPASIZE, dev_priv->regfile.saveDSPASIZE); 377 + I915_WRITE(_DSPAPOS, dev_priv->regfile.saveDSPAPOS); 378 + I915_WRITE(_PIPEASRC, dev_priv->regfile.savePIPEASRC); 379 + I915_WRITE(_DSPAADDR, dev_priv->regfile.saveDSPAADDR); 380 + I915_WRITE(_DSPASTRIDE, dev_priv->regfile.saveDSPASTRIDE); 381 + if (INTEL_INFO(dev)->gen >= 4) { 382 + I915_WRITE(_DSPASURF, dev_priv->regfile.saveDSPASURF); 383 + I915_WRITE(_DSPATILEOFF, dev_priv->regfile.saveDSPATILEOFF); 384 + } 385 + 386 + I915_WRITE(_PIPEACONF, dev_priv->regfile.savePIPEACONF); 387 + 388 + i915_restore_palette(dev, PIPE_A); 389 + /* Enable the plane */ 390 + I915_WRITE(_DSPACNTR, dev_priv->regfile.saveDSPACNTR); 391 + I915_WRITE(_DSPAADDR, I915_READ(_DSPAADDR)); 392 + 393 + /* Pipe & plane B info */ 394 + if (dev_priv->regfile.saveDPLL_B & DPLL_VCO_ENABLE) { 395 + I915_WRITE(dpll_b_reg, dev_priv->regfile.saveDPLL_B & 396 + ~DPLL_VCO_ENABLE); 397 + POSTING_READ(dpll_b_reg); 398 + udelay(150); 399 + } 400 + I915_WRITE(fpb0_reg, dev_priv->regfile.saveFPB0); 401 + I915_WRITE(fpb1_reg, dev_priv->regfile.saveFPB1); 402 + /* Actually enable it */ 403 + I915_WRITE(dpll_b_reg, dev_priv->regfile.saveDPLL_B); 404 + POSTING_READ(dpll_b_reg); 405 + udelay(150); 406 + if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { 407 + I915_WRITE(_DPLL_B_MD, dev_priv->regfile.saveDPLL_B_MD); 408 + POSTING_READ(_DPLL_B_MD); 409 + } 410 + udelay(150); 411 + 412 + /* Restore mode */ 413 + I915_WRITE(_HTOTAL_B, dev_priv->regfile.saveHTOTAL_B); 414 + I915_WRITE(_HBLANK_B, dev_priv->regfile.saveHBLANK_B); 415 + I915_WRITE(_HSYNC_B, dev_priv->regfile.saveHSYNC_B); 416 + I915_WRITE(_VTOTAL_B, dev_priv->regfile.saveVTOTAL_B); 417 + I915_WRITE(_VBLANK_B, dev_priv->regfile.saveVBLANK_B); 418 + I915_WRITE(_VSYNC_B, dev_priv->regfile.saveVSYNC_B); 419 + if (!HAS_PCH_SPLIT(dev)) 420 + I915_WRITE(_BCLRPAT_B, dev_priv->regfile.saveBCLRPAT_B); 421 + 422 + if (HAS_PCH_SPLIT(dev)) { 423 + I915_WRITE(_PIPEB_DATA_M1, dev_priv->regfile.savePIPEB_DATA_M1); 424 + I915_WRITE(_PIPEB_DATA_N1, dev_priv->regfile.savePIPEB_DATA_N1); 425 + I915_WRITE(_PIPEB_LINK_M1, dev_priv->regfile.savePIPEB_LINK_M1); 426 + I915_WRITE(_PIPEB_LINK_N1, dev_priv->regfile.savePIPEB_LINK_N1); 427 + 428 + I915_WRITE(_FDI_RXB_CTL, dev_priv->regfile.saveFDI_RXB_CTL); 429 + I915_WRITE(_FDI_TXB_CTL, dev_priv->regfile.saveFDI_TXB_CTL); 430 + 431 + I915_WRITE(_PFB_CTL_1, dev_priv->regfile.savePFB_CTL_1); 432 + I915_WRITE(_PFB_WIN_SZ, dev_priv->regfile.savePFB_WIN_SZ); 433 + I915_WRITE(_PFB_WIN_POS, dev_priv->regfile.savePFB_WIN_POS); 434 + 435 + I915_WRITE(_TRANSBCONF, dev_priv->regfile.saveTRANSBCONF); 436 + I915_WRITE(_TRANS_HTOTAL_B, dev_priv->regfile.saveTRANS_HTOTAL_B); 437 + I915_WRITE(_TRANS_HBLANK_B, dev_priv->regfile.saveTRANS_HBLANK_B); 438 + I915_WRITE(_TRANS_HSYNC_B, dev_priv->regfile.saveTRANS_HSYNC_B); 439 + I915_WRITE(_TRANS_VTOTAL_B, dev_priv->regfile.saveTRANS_VTOTAL_B); 440 + I915_WRITE(_TRANS_VBLANK_B, dev_priv->regfile.saveTRANS_VBLANK_B); 441 + I915_WRITE(_TRANS_VSYNC_B, dev_priv->regfile.saveTRANS_VSYNC_B); 442 + } 443 + 444 + /* Restore plane info */ 445 + I915_WRITE(_DSPBSIZE, dev_priv->regfile.saveDSPBSIZE); 446 + I915_WRITE(_DSPBPOS, dev_priv->regfile.saveDSPBPOS); 447 + I915_WRITE(_PIPEBSRC, dev_priv->regfile.savePIPEBSRC); 448 + I915_WRITE(_DSPBADDR, dev_priv->regfile.saveDSPBADDR); 449 + I915_WRITE(_DSPBSTRIDE, dev_priv->regfile.saveDSPBSTRIDE); 450 + if (INTEL_INFO(dev)->gen >= 4) { 451 + I915_WRITE(_DSPBSURF, dev_priv->regfile.saveDSPBSURF); 452 + I915_WRITE(_DSPBTILEOFF, dev_priv->regfile.saveDSPBTILEOFF); 453 + } 454 + 455 + I915_WRITE(_PIPEBCONF, dev_priv->regfile.savePIPEBCONF); 456 + 457 + i915_restore_palette(dev, PIPE_B); 458 + /* Enable the plane */ 459 + I915_WRITE(_DSPBCNTR, dev_priv->regfile.saveDSPBCNTR); 460 + I915_WRITE(_DSPBADDR, I915_READ(_DSPBADDR)); 461 + 462 + /* Cursor state */ 463 + I915_WRITE(_CURAPOS, dev_priv->regfile.saveCURAPOS); 464 + I915_WRITE(_CURACNTR, dev_priv->regfile.saveCURACNTR); 465 + I915_WRITE(_CURABASE, dev_priv->regfile.saveCURABASE); 466 + I915_WRITE(_CURBPOS, dev_priv->regfile.saveCURBPOS); 467 + I915_WRITE(_CURBCNTR, dev_priv->regfile.saveCURBCNTR); 468 + I915_WRITE(_CURBBASE, dev_priv->regfile.saveCURBBASE); 469 + if (IS_GEN2(dev)) 470 + I915_WRITE(CURSIZE, dev_priv->regfile.saveCURSIZE); 471 + 472 + /* CRT state */ 473 + if (HAS_PCH_SPLIT(dev)) 474 + I915_WRITE(PCH_ADPA, dev_priv->regfile.saveADPA); 475 + else 476 + I915_WRITE(ADPA, dev_priv->regfile.saveADPA); 477 + 478 + return; 479 + }