i915_suspend.c revision 183573
1/* i915_suspend.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- 2 */ 3/* 4 * 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 6 * All Rights Reserved. 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 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD: head/sys/dev/drm/i915_suspend.c 183573 2008-10-03 16:59:11Z rnoland $"); 32 33#include "dev/drm/drmP.h" 34#include "dev/drm/drm.h" 35#include "dev/drm/i915_drm.h" 36#include "dev/drm/i915_drv.h" 37 38static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) 39{ 40 struct drm_i915_private *dev_priv = dev->dev_private; 41 42 if (pipe == PIPE_A) 43 return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); 44 else 45 return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); 46} 47 48static void i915_save_palette(struct drm_device *dev, enum pipe pipe) 49{ 50 struct drm_i915_private *dev_priv = dev->dev_private; 51 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); 52 u32 *array; 53 int i; 54 55 if (!i915_pipe_enabled(dev, pipe)) 56 return; 57 58 if (pipe == PIPE_A) 59 array = dev_priv->save_palette_a; 60 else 61 array = dev_priv->save_palette_b; 62 63 for(i = 0; i < 256; i++) 64 array[i] = I915_READ(reg + (i << 2)); 65} 66 67static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) 68{ 69 struct drm_i915_private *dev_priv = dev->dev_private; 70 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); 71 u32 *array; 72 int i; 73 74 if (!i915_pipe_enabled(dev, pipe)) 75 return; 76 77 if (pipe == PIPE_A) 78 array = dev_priv->save_palette_a; 79 else 80 array = dev_priv->save_palette_b; 81 82 for(i = 0; i < 256; i++) 83 I915_WRITE(reg + (i << 2), array[i]); 84} 85 86static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) 87{ 88 struct drm_i915_private *dev_priv = dev->dev_private; 89 90 I915_WRITE8(index_port, reg); 91 return I915_READ8(data_port); 92} 93 94static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) 95{ 96 struct drm_i915_private *dev_priv = dev->dev_private; 97 98 I915_READ8(st01); 99 I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); 100 return I915_READ8(VGA_AR_DATA_READ); 101} 102 103static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) 104{ 105 struct drm_i915_private *dev_priv = dev->dev_private; 106 107 I915_READ8(st01); 108 I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); 109 I915_WRITE8(VGA_AR_DATA_WRITE, val); 110} 111 112static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) 113{ 114 struct drm_i915_private *dev_priv = dev->dev_private; 115 116 I915_WRITE8(index_port, reg); 117 I915_WRITE8(data_port, val); 118} 119 120static void i915_save_vga(struct drm_device *dev) 121{ 122 struct drm_i915_private *dev_priv = dev->dev_private; 123 int i; 124 u16 cr_index, cr_data, st01; 125 126 /* VGA color palette registers */ 127 dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); 128 /* DACCRX automatically increments during read */ 129 I915_WRITE8(VGA_DACRX, 0); 130 /* Read 3 bytes of color data from each index */ 131 for (i = 0; i < 256 * 3; i++) 132 dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA); 133 134 /* MSR bits */ 135 dev_priv->saveMSR = I915_READ8(VGA_MSR_READ); 136 if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { 137 cr_index = VGA_CR_INDEX_CGA; 138 cr_data = VGA_CR_DATA_CGA; 139 st01 = VGA_ST01_CGA; 140 } else { 141 cr_index = VGA_CR_INDEX_MDA; 142 cr_data = VGA_CR_DATA_MDA; 143 st01 = VGA_ST01_MDA; 144 } 145 146 /* CRT controller regs */ 147 i915_write_indexed(dev, cr_index, cr_data, 0x11, 148 i915_read_indexed(dev, cr_index, cr_data, 0x11) & 149 (~0x80)); 150 for (i = 0; i <= 0x24; i++) 151 dev_priv->saveCR[i] = 152 i915_read_indexed(dev, cr_index, cr_data, i); 153 /* Make sure we don't turn off CR group 0 writes */ 154 dev_priv->saveCR[0x11] &= ~0x80; 155 156 /* Attribute controller registers */ 157 I915_READ8(st01); 158 dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX); 159 for (i = 0; i <= 0x14; i++) 160 dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0); 161 I915_READ8(st01); 162 I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX); 163 I915_READ8(st01); 164 165 /* Graphics controller registers */ 166 for (i = 0; i < 9; i++) 167 dev_priv->saveGR[i] = 168 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i); 169 170 dev_priv->saveGR[0x10] = 171 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10); 172 dev_priv->saveGR[0x11] = 173 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11); 174 dev_priv->saveGR[0x18] = 175 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18); 176 177 /* Sequencer registers */ 178 for (i = 0; i < 8; i++) 179 dev_priv->saveSR[i] = 180 i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i); 181} 182 183static void i915_restore_vga(struct drm_device *dev) 184{ 185 struct drm_i915_private *dev_priv = dev->dev_private; 186 int i; 187 u16 cr_index, cr_data, st01; 188 189 /* MSR bits */ 190 I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR); 191 if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { 192 cr_index = VGA_CR_INDEX_CGA; 193 cr_data = VGA_CR_DATA_CGA; 194 st01 = VGA_ST01_CGA; 195 } else { 196 cr_index = VGA_CR_INDEX_MDA; 197 cr_data = VGA_CR_DATA_MDA; 198 st01 = VGA_ST01_MDA; 199 } 200 201 /* Sequencer registers, don't write SR07 */ 202 for (i = 0; i < 7; i++) 203 i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i, 204 dev_priv->saveSR[i]); 205 206 /* CRT controller regs */ 207 /* Enable CR group 0 writes */ 208 i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); 209 for (i = 0; i <= 0x24; i++) 210 i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]); 211 212 /* Graphics controller regs */ 213 for (i = 0; i < 9; i++) 214 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i, 215 dev_priv->saveGR[i]); 216 217 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10, 218 dev_priv->saveGR[0x10]); 219 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11, 220 dev_priv->saveGR[0x11]); 221 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18, 222 dev_priv->saveGR[0x18]); 223 224 /* Attribute controller registers */ 225 I915_READ8(st01); /* switch back to index mode */ 226 for (i = 0; i <= 0x14; i++) 227 i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0); 228 I915_READ8(st01); /* switch back to index mode */ 229 I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20); 230 I915_READ8(st01); 231 232 /* VGA color palette registers */ 233 I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); 234 /* DACCRX automatically increments during read */ 235 I915_WRITE8(VGA_DACWX, 0); 236 /* Read 3 bytes of color data from each index */ 237 for (i = 0; i < 256 * 3; i++) 238 I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]); 239 240} 241 242int i915_save_state(struct drm_device *dev) 243{ 244 struct drm_i915_private *dev_priv = dev->dev_private; 245 int i; 246 247#if defined(__FreeBSD__) 248 dev_priv->saveLBB = (u8) pci_read_config(dev->device, LBB, 1); 249#else 250 pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); 251#endif 252 253 /* Display arbitration control */ 254 dev_priv->saveDSPARB = I915_READ(DSPARB); 255 256 /* Pipe & plane A info */ 257 dev_priv->savePIPEACONF = I915_READ(PIPEACONF); 258 dev_priv->savePIPEASRC = I915_READ(PIPEASRC); 259 dev_priv->saveFPA0 = I915_READ(FPA0); 260 dev_priv->saveFPA1 = I915_READ(FPA1); 261 dev_priv->saveDPLL_A = I915_READ(DPLL_A); 262 if (IS_I965G(dev)) 263 dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); 264 dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); 265 dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); 266 dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); 267 dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); 268 dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); 269 dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); 270 dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); 271 272 dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); 273 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); 274 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); 275 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); 276 dev_priv->saveDSPAADDR = I915_READ(DSPAADDR); 277 if (IS_I965G(dev)) { 278 dev_priv->saveDSPASURF = I915_READ(DSPASURF); 279 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); 280 } 281 i915_save_palette(dev, PIPE_A); 282 dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT); 283 284 /* Pipe & plane B info */ 285 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); 286 dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); 287 dev_priv->saveFPB0 = I915_READ(FPB0); 288 dev_priv->saveFPB1 = I915_READ(FPB1); 289 dev_priv->saveDPLL_B = I915_READ(DPLL_B); 290 if (IS_I965G(dev)) 291 dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); 292 dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); 293 dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); 294 dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); 295 dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); 296 dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); 297 dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); 298 dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); 299 300 dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); 301 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); 302 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); 303 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); 304 dev_priv->saveDSPBADDR = I915_READ(DSPBADDR); 305 if (IS_I965GM(dev) || IS_GM45(dev)) { 306 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); 307 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); 308 } 309 i915_save_palette(dev, PIPE_B); 310 dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); 311 312 /* CRT state */ 313 dev_priv->saveADPA = I915_READ(ADPA); 314 315 /* LVDS state */ 316 dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); 317 dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); 318 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); 319 if (IS_I965G(dev)) 320 dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); 321 if (IS_MOBILE(dev) && !IS_I830(dev)) 322 dev_priv->saveLVDS = I915_READ(LVDS); 323 if (!IS_I830(dev) && !IS_845G(dev)) 324 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); 325 dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); 326 dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); 327 dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); 328 329 /* FIXME: save TV & SDVO state */ 330 331 /* FBC state */ 332 dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); 333 dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); 334 dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); 335 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); 336 337 /* Interrupt state */ 338 dev_priv->saveIIR = I915_READ(IIR); 339 dev_priv->saveIER = I915_READ(IER); 340 dev_priv->saveIMR = I915_READ(IMR); 341 342 /* VGA state */ 343 dev_priv->saveVGA0 = I915_READ(VGA0); 344 dev_priv->saveVGA1 = I915_READ(VGA1); 345 dev_priv->saveVGA_PD = I915_READ(VGA_PD); 346 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); 347 348 /* Clock gating state */ 349 dev_priv->saveD_STATE = I915_READ(D_STATE); 350 dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); 351 352 /* Cache mode state */ 353 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); 354 355 /* Memory Arbitration state */ 356 dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); 357 358 /* Scratch space */ 359 for (i = 0; i < 16; i++) { 360 dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); 361 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); 362 } 363 for (i = 0; i < 3; i++) 364 dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); 365 366 i915_save_vga(dev); 367 368 return 0; 369} 370 371int i915_restore_state(struct drm_device *dev) 372{ 373 struct drm_i915_private *dev_priv = dev->dev_private; 374 int i; 375 376#if defined(__FreeBSD__) 377 pci_write_config(dev->device, LBB, dev_priv->saveLBB, 1); 378#else 379 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); 380#endif 381 382 I915_WRITE(DSPARB, dev_priv->saveDSPARB); 383 384 /* Pipe & plane A info */ 385 /* Prime the clock */ 386 if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { 387 I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & 388 ~DPLL_VCO_ENABLE); 389 DRM_UDELAY(150); 390 } 391 I915_WRITE(FPA0, dev_priv->saveFPA0); 392 I915_WRITE(FPA1, dev_priv->saveFPA1); 393 /* Actually enable it */ 394 I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); 395 DRM_UDELAY(150); 396 if (IS_I965G(dev)) 397 I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); 398 DRM_UDELAY(150); 399 400 /* Restore mode */ 401 I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); 402 I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); 403 I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); 404 I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); 405 I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); 406 I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); 407 I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); 408 409 /* Restore plane info */ 410 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); 411 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); 412 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); 413 I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); 414 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); 415 if (IS_I965G(dev)) { 416 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); 417 I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); 418 } 419 420 I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); 421 422 i915_restore_palette(dev, PIPE_A); 423 /* Enable the plane */ 424 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); 425 I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); 426 427 /* Pipe & plane B info */ 428 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { 429 I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & 430 ~DPLL_VCO_ENABLE); 431 DRM_UDELAY(150); 432 } 433 I915_WRITE(FPB0, dev_priv->saveFPB0); 434 I915_WRITE(FPB1, dev_priv->saveFPB1); 435 /* Actually enable it */ 436 I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); 437 DRM_UDELAY(150); 438 if (IS_I965G(dev)) 439 I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); 440 DRM_UDELAY(150); 441 442 /* Restore mode */ 443 I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); 444 I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); 445 I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); 446 I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); 447 I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); 448 I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); 449 I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); 450 451 /* Restore plane info */ 452 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); 453 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); 454 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); 455 I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); 456 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); 457 if (IS_I965G(dev)) { 458 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); 459 I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); 460 } 461 462 I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); 463 464 i915_restore_palette(dev, PIPE_B); 465 /* Enable the plane */ 466 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); 467 I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); 468 469 /* CRT state */ 470 I915_WRITE(ADPA, dev_priv->saveADPA); 471 472 /* LVDS state */ 473 if (IS_I965G(dev)) 474 I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); 475 if (IS_MOBILE(dev) && !IS_I830(dev)) 476 I915_WRITE(LVDS, dev_priv->saveLVDS); 477 if (!IS_I830(dev) && !IS_845G(dev)) 478 I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); 479 480 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); 481 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); 482 I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); 483 I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); 484 I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); 485 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); 486 487 /* FIXME: restore TV & SDVO state */ 488 489 /* FBC info */ 490 I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); 491 I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); 492 I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); 493 I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); 494 495 /* VGA state */ 496 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); 497 I915_WRITE(VGA0, dev_priv->saveVGA0); 498 I915_WRITE(VGA1, dev_priv->saveVGA1); 499 I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); 500 DRM_UDELAY(150); 501 502 /* Clock gating state */ 503 I915_WRITE (D_STATE, dev_priv->saveD_STATE); 504 I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); 505 506 /* Cache mode state */ 507 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); 508 509 /* Memory arbitration state */ 510 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); 511 512 for (i = 0; i < 16; i++) { 513 I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); 514 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); 515 } 516 for (i = 0; i < 3; i++) 517 I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); 518 519 i915_restore_vga(dev); 520 521 return 0; 522} 523 524