1 /* 2 * 3 * Copyright 2008 (c) Intel Corporation 4 * Jesse Barnes <jbarnes@virtuousgeek.org> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 #include "drmP.h" 28 #include "drm.h" 29 #include "i915_drm.h" 30 #include "intel_drv.h" 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 if (HAS_PCH_SPLIT(dev)) { 38 dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; 39 } else { 40 dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; 41 } 42 43 return (I915_READ(dpll_reg) & DPLL_VCO_ENABLE); 44 } 45 46 static void i915_save_palette(struct drm_device *dev, enum pipe pipe) 47 { 48 struct drm_i915_private *dev_priv = dev->dev_private; 49 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); 50 u32 *array; 51 int i; 52 53 if (!i915_pipe_enabled(dev, pipe)) 54 return; 55 56 if (HAS_PCH_SPLIT(dev)) 57 reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; 58 59 if (pipe == PIPE_A) 60 array = dev_priv->save_palette_a; 61 else 62 array = dev_priv->save_palette_b; 63 64 for(i = 0; i < 256; i++) 65 array[i] = I915_READ(reg + (i << 2)); 66 } 67 68 static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) 69 { 70 struct drm_i915_private *dev_priv = dev->dev_private; 71 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); 72 u32 *array; 73 int i; 74 75 if (!i915_pipe_enabled(dev, pipe)) 76 return; 77 78 if (HAS_PCH_SPLIT(dev)) 79 reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; 80 81 if (pipe == PIPE_A) 82 array = dev_priv->save_palette_a; 83 else 84 array = dev_priv->save_palette_b; 85 86 for(i = 0; i < 256; i++) 87 I915_WRITE(reg + (i << 2), array[i]); 88 } 89 90 static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) 91 { 92 struct drm_i915_private *dev_priv = dev->dev_private; 93 94 I915_WRITE8(index_port, reg); 95 return I915_READ8(data_port); 96 } 97 98 static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) 99 { 100 struct drm_i915_private *dev_priv = dev->dev_private; 101 102 I915_READ8(st01); 103 I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); 104 return I915_READ8(VGA_AR_DATA_READ); 105 } 106 107 static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) 108 { 109 struct drm_i915_private *dev_priv = dev->dev_private; 110 111 I915_READ8(st01); 112 I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); 113 I915_WRITE8(VGA_AR_DATA_WRITE, val); 114 } 115 116 static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) 117 { 118 struct drm_i915_private *dev_priv = dev->dev_private; 119 120 I915_WRITE8(index_port, reg); 121 I915_WRITE8(data_port, val); 122 } 123 124 static void i915_save_vga(struct drm_device *dev) 125 { 126 struct drm_i915_private *dev_priv = dev->dev_private; 127 int i; 128 u16 cr_index, cr_data, st01; 129 130 /* VGA color palette registers */ 131 dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); 132 133 /* MSR bits */ 134 dev_priv->saveMSR = I915_READ8(VGA_MSR_READ); 135 if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { 136 cr_index = VGA_CR_INDEX_CGA; 137 cr_data = VGA_CR_DATA_CGA; 138 st01 = VGA_ST01_CGA; 139 } else { 140 cr_index = VGA_CR_INDEX_MDA; 141 cr_data = VGA_CR_DATA_MDA; 142 st01 = VGA_ST01_MDA; 143 } 144 145 /* CRT controller regs */ 146 i915_write_indexed(dev, cr_index, cr_data, 0x11, 147 i915_read_indexed(dev, cr_index, cr_data, 0x11) & 148 (~0x80)); 149 for (i = 0; i <= 0x24; i++) 150 dev_priv->saveCR[i] = 151 i915_read_indexed(dev, cr_index, cr_data, i); 152 /* Make sure we don't turn off CR group 0 writes */ 153 dev_priv->saveCR[0x11] &= ~0x80; 154 155 /* Attribute controller registers */ 156 I915_READ8(st01); 157 dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX); 158 for (i = 0; i <= 0x14; i++) 159 dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0); 160 I915_READ8(st01); 161 I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX); 162 I915_READ8(st01); 163 164 /* Graphics controller registers */ 165 for (i = 0; i < 9; i++) 166 dev_priv->saveGR[i] = 167 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i); 168 169 dev_priv->saveGR[0x10] = 170 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10); 171 dev_priv->saveGR[0x11] = 172 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11); 173 dev_priv->saveGR[0x18] = 174 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18); 175 176 /* Sequencer registers */ 177 for (i = 0; i < 8; i++) 178 dev_priv->saveSR[i] = 179 i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i); 180 } 181 182 static void i915_restore_vga(struct drm_device *dev) 183 { 184 struct drm_i915_private *dev_priv = dev->dev_private; 185 int i; 186 u16 cr_index, cr_data, st01; 187 188 /* MSR bits */ 189 I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR); 190 if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { 191 cr_index = VGA_CR_INDEX_CGA; 192 cr_data = VGA_CR_DATA_CGA; 193 st01 = VGA_ST01_CGA; 194 } else { 195 cr_index = VGA_CR_INDEX_MDA; 196 cr_data = VGA_CR_DATA_MDA; 197 st01 = VGA_ST01_MDA; 198 } 199 200 /* Sequencer registers, don't write SR07 */ 201 for (i = 0; i < 7; i++) 202 i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i, 203 dev_priv->saveSR[i]); 204 205 /* CRT controller regs */ 206 /* Enable CR group 0 writes */ 207 i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); 208 for (i = 0; i <= 0x24; i++) 209 i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]); 210 211 /* Graphics controller regs */ 212 for (i = 0; i < 9; i++) 213 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i, 214 dev_priv->saveGR[i]); 215 216 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10, 217 dev_priv->saveGR[0x10]); 218 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11, 219 dev_priv->saveGR[0x11]); 220 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18, 221 dev_priv->saveGR[0x18]); 222 223 /* Attribute controller registers */ 224 I915_READ8(st01); /* switch back to index mode */ 225 for (i = 0; i <= 0x14; i++) 226 i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0); 227 I915_READ8(st01); /* switch back to index mode */ 228 I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20); 229 I915_READ8(st01); 230 231 /* VGA color palette registers */ 232 I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); 233 } 234 235 static void i915_save_modeset_reg(struct drm_device *dev) 236 { 237 struct drm_i915_private *dev_priv = dev->dev_private; 238 239 if (drm_core_check_feature(dev, DRIVER_MODESET)) 240 return; 241 242 /* Cursor state */ 243 dev_priv->saveCURACNTR = I915_READ(CURACNTR); 244 dev_priv->saveCURAPOS = I915_READ(CURAPOS); 245 dev_priv->saveCURABASE = I915_READ(CURABASE); 246 dev_priv->saveCURBCNTR = I915_READ(CURBCNTR); 247 dev_priv->saveCURBPOS = I915_READ(CURBPOS); 248 dev_priv->saveCURBBASE = I915_READ(CURBBASE); 249 if (IS_GEN2(dev)) 250 dev_priv->saveCURSIZE = I915_READ(CURSIZE); 251 252 if (HAS_PCH_SPLIT(dev)) { 253 dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); 254 dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); 255 } 256 257 /* Pipe & plane A info */ 258 dev_priv->savePIPEACONF = I915_READ(PIPEACONF); 259 dev_priv->savePIPEASRC = I915_READ(PIPEASRC); 260 if (HAS_PCH_SPLIT(dev)) { 261 dev_priv->saveFPA0 = I915_READ(PCH_FPA0); 262 dev_priv->saveFPA1 = I915_READ(PCH_FPA1); 263 dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); 264 } else { 265 dev_priv->saveFPA0 = I915_READ(FPA0); 266 dev_priv->saveFPA1 = I915_READ(FPA1); 267 dev_priv->saveDPLL_A = I915_READ(DPLL_A); 268 } 269 if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) 270 dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); 271 dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); 272 dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); 273 dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); 274 dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); 275 dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); 276 dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); 277 if (!HAS_PCH_SPLIT(dev)) 278 dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); 279 280 if (HAS_PCH_SPLIT(dev)) { 281 dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); 282 dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); 283 dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); 284 dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1); 285 286 dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); 287 dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); 288 289 dev_priv->savePFA_CTL_1 = I915_READ(PFA_CTL_1); 290 dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); 291 dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); 292 293 dev_priv->saveTRANSACONF = I915_READ(TRANSACONF); 294 dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); 295 dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); 296 dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); 297 dev_priv->saveTRANS_VTOTAL_A = I915_READ(TRANS_VTOTAL_A); 298 dev_priv->saveTRANS_VBLANK_A = I915_READ(TRANS_VBLANK_A); 299 dev_priv->saveTRANS_VSYNC_A = I915_READ(TRANS_VSYNC_A); 300 } 301 302 dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); 303 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); 304 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); 305 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); 306 dev_priv->saveDSPAADDR = I915_READ(DSPAADDR); 307 if (INTEL_INFO(dev)->gen >= 4) { 308 dev_priv->saveDSPASURF = I915_READ(DSPASURF); 309 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); 310 } 311 i915_save_palette(dev, PIPE_A); 312 dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT); 313 314 /* Pipe & plane B info */ 315 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); 316 dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); 317 if (HAS_PCH_SPLIT(dev)) { 318 dev_priv->saveFPB0 = I915_READ(PCH_FPB0); 319 dev_priv->saveFPB1 = I915_READ(PCH_FPB1); 320 dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); 321 } else { 322 dev_priv->saveFPB0 = I915_READ(FPB0); 323 dev_priv->saveFPB1 = I915_READ(FPB1); 324 dev_priv->saveDPLL_B = I915_READ(DPLL_B); 325 } 326 if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) 327 dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); 328 dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); 329 dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); 330 dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); 331 dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); 332 dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); 333 dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); 334 if (!HAS_PCH_SPLIT(dev)) 335 dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); 336 337 if (HAS_PCH_SPLIT(dev)) { 338 dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); 339 dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); 340 dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); 341 dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1); 342 343 dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); 344 dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); 345 346 dev_priv->savePFB_CTL_1 = I915_READ(PFB_CTL_1); 347 dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); 348 dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); 349 350 dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF); 351 dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); 352 dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); 353 dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); 354 dev_priv->saveTRANS_VTOTAL_B = I915_READ(TRANS_VTOTAL_B); 355 dev_priv->saveTRANS_VBLANK_B = I915_READ(TRANS_VBLANK_B); 356 dev_priv->saveTRANS_VSYNC_B = I915_READ(TRANS_VSYNC_B); 357 } 358 359 dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); 360 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); 361 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); 362 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); 363 dev_priv->saveDSPBADDR = I915_READ(DSPBADDR); 364 if (INTEL_INFO(dev)->gen >= 4) { 365 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); 366 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); 367 } 368 i915_save_palette(dev, PIPE_B); 369 dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); 370 return; 371 } 372 373 static void i915_restore_modeset_reg(struct drm_device *dev) 374 { 375 struct drm_i915_private *dev_priv = dev->dev_private; 376 int dpll_a_reg, fpa0_reg, fpa1_reg; 377 int dpll_b_reg, fpb0_reg, fpb1_reg; 378 379 if (drm_core_check_feature(dev, DRIVER_MODESET)) 380 return; 381 382 if (HAS_PCH_SPLIT(dev)) { 383 dpll_a_reg = PCH_DPLL_A; 384 dpll_b_reg = PCH_DPLL_B; 385 fpa0_reg = PCH_FPA0; 386 fpb0_reg = PCH_FPB0; 387 fpa1_reg = PCH_FPA1; 388 fpb1_reg = PCH_FPB1; 389 } else { 390 dpll_a_reg = DPLL_A; 391 dpll_b_reg = DPLL_B; 392 fpa0_reg = FPA0; 393 fpb0_reg = FPB0; 394 fpa1_reg = FPA1; 395 fpb1_reg = FPB1; 396 } 397 398 if (HAS_PCH_SPLIT(dev)) { 399 I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); 400 I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); 401 } 402 403 /* Pipe & plane A info */ 404 /* Prime the clock */ 405 if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { 406 I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & 407 ~DPLL_VCO_ENABLE); 408 POSTING_READ(dpll_a_reg); 409 udelay(150); 410 } 411 I915_WRITE(fpa0_reg, dev_priv->saveFPA0); 412 I915_WRITE(fpa1_reg, dev_priv->saveFPA1); 413 /* Actually enable it */ 414 I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); 415 POSTING_READ(dpll_a_reg); 416 udelay(150); 417 if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { 418 I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); 419 POSTING_READ(DPLL_A_MD); 420 } 421 udelay(150); 422 423 /* Restore mode */ 424 I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); 425 I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); 426 I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); 427 I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); 428 I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); 429 I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); 430 if (!HAS_PCH_SPLIT(dev)) 431 I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); 432 433 if (HAS_PCH_SPLIT(dev)) { 434 I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); 435 I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); 436 I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); 437 I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1); 438 439 I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); 440 I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); 441 442 I915_WRITE(PFA_CTL_1, dev_priv->savePFA_CTL_1); 443 I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); 444 I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); 445 446 I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF); 447 I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); 448 I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); 449 I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); 450 I915_WRITE(TRANS_VTOTAL_A, dev_priv->saveTRANS_VTOTAL_A); 451 I915_WRITE(TRANS_VBLANK_A, dev_priv->saveTRANS_VBLANK_A); 452 I915_WRITE(TRANS_VSYNC_A, dev_priv->saveTRANS_VSYNC_A); 453 } 454 455 /* Restore plane info */ 456 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); 457 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); 458 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); 459 I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); 460 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); 461 if (INTEL_INFO(dev)->gen >= 4) { 462 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); 463 I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); 464 } 465 466 I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); 467 468 i915_restore_palette(dev, PIPE_A); 469 /* Enable the plane */ 470 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); 471 I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); 472 473 /* Pipe & plane B info */ 474 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { 475 I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & 476 ~DPLL_VCO_ENABLE); 477 POSTING_READ(dpll_b_reg); 478 udelay(150); 479 } 480 I915_WRITE(fpb0_reg, dev_priv->saveFPB0); 481 I915_WRITE(fpb1_reg, dev_priv->saveFPB1); 482 /* Actually enable it */ 483 I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); 484 POSTING_READ(dpll_b_reg); 485 udelay(150); 486 if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) { 487 I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); 488 POSTING_READ(DPLL_B_MD); 489 } 490 udelay(150); 491 492 /* Restore mode */ 493 I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); 494 I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); 495 I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); 496 I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); 497 I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); 498 I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); 499 if (!HAS_PCH_SPLIT(dev)) 500 I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); 501 502 if (HAS_PCH_SPLIT(dev)) { 503 I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); 504 I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); 505 I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); 506 I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1); 507 508 I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); 509 I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); 510 511 I915_WRITE(PFB_CTL_1, dev_priv->savePFB_CTL_1); 512 I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); 513 I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); 514 515 I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF); 516 I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); 517 I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); 518 I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); 519 I915_WRITE(TRANS_VTOTAL_B, dev_priv->saveTRANS_VTOTAL_B); 520 I915_WRITE(TRANS_VBLANK_B, dev_priv->saveTRANS_VBLANK_B); 521 I915_WRITE(TRANS_VSYNC_B, dev_priv->saveTRANS_VSYNC_B); 522 } 523 524 /* Restore plane info */ 525 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); 526 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); 527 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); 528 I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); 529 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); 530 if (INTEL_INFO(dev)->gen >= 4) { 531 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); 532 I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); 533 } 534 535 I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); 536 537 i915_restore_palette(dev, PIPE_B); 538 /* Enable the plane */ 539 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); 540 I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); 541 542 /* Cursor state */ 543 I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); 544 I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); 545 I915_WRITE(CURABASE, dev_priv->saveCURABASE); 546 I915_WRITE(CURBPOS, dev_priv->saveCURBPOS); 547 I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR); 548 I915_WRITE(CURBBASE, dev_priv->saveCURBBASE); 549 if (IS_GEN2(dev)) 550 I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); 551 552 return; 553 } 554 555 void i915_save_display(struct drm_device *dev) 556 { 557 struct drm_i915_private *dev_priv = dev->dev_private; 558 559 /* Display arbitration control */ 560 dev_priv->saveDSPARB = I915_READ(DSPARB); 561 562 /* This is only meaningful in non-KMS mode */ 563 /* Don't save them in KMS mode */ 564 i915_save_modeset_reg(dev); 565 566 /* CRT state */ 567 if (HAS_PCH_SPLIT(dev)) { 568 dev_priv->saveADPA = I915_READ(PCH_ADPA); 569 } else { 570 dev_priv->saveADPA = I915_READ(ADPA); 571 } 572 573 /* LVDS state */ 574 if (HAS_PCH_SPLIT(dev)) { 575 dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); 576 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); 577 dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); 578 dev_priv->saveBLC_CPU_PWM_CTL = I915_READ(BLC_PWM_CPU_CTL); 579 dev_priv->saveBLC_CPU_PWM_CTL2 = I915_READ(BLC_PWM_CPU_CTL2); 580 dev_priv->saveLVDS = I915_READ(PCH_LVDS); 581 } else { 582 dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); 583 dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); 584 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); 585 dev_priv->saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); 586 if (INTEL_INFO(dev)->gen >= 4) 587 dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); 588 if (IS_MOBILE(dev) && !IS_I830(dev)) 589 dev_priv->saveLVDS = I915_READ(LVDS); 590 } 591 592 if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) 593 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); 594 595 if (HAS_PCH_SPLIT(dev)) { 596 dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); 597 dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); 598 dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); 599 } else { 600 dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); 601 dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); 602 dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); 603 } 604 605 /* Display Port state */ 606 if (SUPPORTS_INTEGRATED_DP(dev)) { 607 dev_priv->saveDP_B = I915_READ(DP_B); 608 dev_priv->saveDP_C = I915_READ(DP_C); 609 dev_priv->saveDP_D = I915_READ(DP_D); 610 dev_priv->savePIPEA_GMCH_DATA_M = I915_READ(PIPEA_GMCH_DATA_M); 611 dev_priv->savePIPEB_GMCH_DATA_M = I915_READ(PIPEB_GMCH_DATA_M); 612 dev_priv->savePIPEA_GMCH_DATA_N = I915_READ(PIPEA_GMCH_DATA_N); 613 dev_priv->savePIPEB_GMCH_DATA_N = I915_READ(PIPEB_GMCH_DATA_N); 614 dev_priv->savePIPEA_DP_LINK_M = I915_READ(PIPEA_DP_LINK_M); 615 dev_priv->savePIPEB_DP_LINK_M = I915_READ(PIPEB_DP_LINK_M); 616 dev_priv->savePIPEA_DP_LINK_N = I915_READ(PIPEA_DP_LINK_N); 617 dev_priv->savePIPEB_DP_LINK_N = I915_READ(PIPEB_DP_LINK_N); 618 } 619 /* FIXME: save TV & SDVO state */ 620 621 /* Only save FBC state on the platform that supports FBC */ 622 if (I915_HAS_FBC(dev)) { 623 if (HAS_PCH_SPLIT(dev)) { 624 dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); 625 } else if (IS_GM45(dev)) { 626 dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); 627 } else { 628 dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); 629 dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); 630 dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); 631 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); 632 } 633 } 634 635 /* VGA state */ 636 dev_priv->saveVGA0 = I915_READ(VGA0); 637 dev_priv->saveVGA1 = I915_READ(VGA1); 638 dev_priv->saveVGA_PD = I915_READ(VGA_PD); 639 if (HAS_PCH_SPLIT(dev)) 640 dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); 641 else 642 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); 643 644 i915_save_vga(dev); 645 } 646 647 void i915_restore_display(struct drm_device *dev) 648 { 649 struct drm_i915_private *dev_priv = dev->dev_private; 650 651 /* Display arbitration */ 652 I915_WRITE(DSPARB, dev_priv->saveDSPARB); 653 654 /* Display port ratios (must be done before clock is set) */ 655 if (SUPPORTS_INTEGRATED_DP(dev)) { 656 I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); 657 I915_WRITE(PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); 658 I915_WRITE(PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); 659 I915_WRITE(PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); 660 I915_WRITE(PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); 661 I915_WRITE(PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); 662 I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); 663 I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); 664 } 665 666 /* This is only meaningful in non-KMS mode */ 667 /* Don't restore them in KMS mode */ 668 i915_restore_modeset_reg(dev); 669 670 /* CRT state */ 671 if (HAS_PCH_SPLIT(dev)) 672 I915_WRITE(PCH_ADPA, dev_priv->saveADPA); 673 else 674 I915_WRITE(ADPA, dev_priv->saveADPA); 675 676 /* LVDS state */ 677 if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) 678 I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); 679 680 if (HAS_PCH_SPLIT(dev)) { 681 I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); 682 } else if (IS_MOBILE(dev) && !IS_I830(dev)) 683 I915_WRITE(LVDS, dev_priv->saveLVDS); 684 685 if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) 686 I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); 687 688 if (HAS_PCH_SPLIT(dev)) { 689 I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); 690 I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); 691 I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); 692 I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); 693 I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); 694 I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); 695 I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); 696 I915_WRITE(PCH_PP_CONTROL, dev_priv->savePP_CONTROL); 697 I915_WRITE(MCHBAR_RENDER_STANDBY, 698 dev_priv->saveMCHBAR_RENDER_STANDBY); 699 } else { 700 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); 701 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); 702 I915_WRITE(BLC_HIST_CTL, dev_priv->saveBLC_HIST_CTL); 703 I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); 704 I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); 705 I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); 706 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); 707 } 708 709 /* Display Port state */ 710 if (SUPPORTS_INTEGRATED_DP(dev)) { 711 I915_WRITE(DP_B, dev_priv->saveDP_B); 712 I915_WRITE(DP_C, dev_priv->saveDP_C); 713 I915_WRITE(DP_D, dev_priv->saveDP_D); 714 } 715 /* FIXME: restore TV & SDVO state */ 716 717 /* only restore FBC info on the platform that supports FBC*/ 718 if (I915_HAS_FBC(dev)) { 719 if (HAS_PCH_SPLIT(dev)) { 720 ironlake_disable_fbc(dev); 721 I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); 722 } else if (IS_GM45(dev)) { 723 g4x_disable_fbc(dev); 724 I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); 725 } else { 726 i8xx_disable_fbc(dev); 727 I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); 728 I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); 729 I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); 730 I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); 731 } 732 } 733 /* VGA state */ 734 if (HAS_PCH_SPLIT(dev)) 735 I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); 736 else 737 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); 738 I915_WRITE(VGA0, dev_priv->saveVGA0); 739 I915_WRITE(VGA1, dev_priv->saveVGA1); 740 I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); 741 POSTING_READ(VGA_PD); 742 udelay(150); 743 744 i915_restore_vga(dev); 745 } 746 747 int i915_save_state(struct drm_device *dev) 748 { 749 struct drm_i915_private *dev_priv = dev->dev_private; 750 int i; 751 752 pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); 753 754 /* Hardware status page */ 755 dev_priv->saveHWS = I915_READ(HWS_PGA); 756 757 i915_save_display(dev); 758 759 /* Interrupt state */ 760 if (HAS_PCH_SPLIT(dev)) { 761 dev_priv->saveDEIER = I915_READ(DEIER); 762 dev_priv->saveDEIMR = I915_READ(DEIMR); 763 dev_priv->saveGTIER = I915_READ(GTIER); 764 dev_priv->saveGTIMR = I915_READ(GTIMR); 765 dev_priv->saveFDI_RXA_IMR = I915_READ(FDI_RXA_IMR); 766 dev_priv->saveFDI_RXB_IMR = I915_READ(FDI_RXB_IMR); 767 dev_priv->saveMCHBAR_RENDER_STANDBY = 768 I915_READ(MCHBAR_RENDER_STANDBY); 769 } else { 770 dev_priv->saveIER = I915_READ(IER); 771 dev_priv->saveIMR = I915_READ(IMR); 772 } 773 774 if (HAS_PCH_SPLIT(dev)) 775 ironlake_disable_drps(dev); 776 777 /* Cache mode state */ 778 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); 779 780 /* Memory Arbitration state */ 781 dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); 782 783 /* Scratch space */ 784 for (i = 0; i < 16; i++) { 785 dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); 786 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); 787 } 788 for (i = 0; i < 3; i++) 789 dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); 790 791 /* Fences */ 792 switch (INTEL_INFO(dev)->gen) { 793 case 6: 794 for (i = 0; i < 16; i++) 795 dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); 796 break; 797 case 5: 798 case 4: 799 for (i = 0; i < 16; i++) 800 dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); 801 break; 802 case 3: 803 if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 804 for (i = 0; i < 8; i++) 805 dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); 806 case 2: 807 for (i = 0; i < 8; i++) 808 dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); 809 break; 810 811 } 812 813 return 0; 814 } 815 816 int i915_restore_state(struct drm_device *dev) 817 { 818 struct drm_i915_private *dev_priv = dev->dev_private; 819 int i; 820 821 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); 822 823 /* Hardware status page */ 824 I915_WRITE(HWS_PGA, dev_priv->saveHWS); 825 826 /* Fences */ 827 switch (INTEL_INFO(dev)->gen) { 828 case 6: 829 for (i = 0; i < 16; i++) 830 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); 831 break; 832 case 5: 833 case 4: 834 for (i = 0; i < 16; i++) 835 I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); 836 break; 837 case 3: 838 case 2: 839 if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 840 for (i = 0; i < 8; i++) 841 I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); 842 for (i = 0; i < 8; i++) 843 I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); 844 break; 845 } 846 847 i915_restore_display(dev); 848 849 /* Interrupt state */ 850 if (HAS_PCH_SPLIT(dev)) { 851 I915_WRITE(DEIER, dev_priv->saveDEIER); 852 I915_WRITE(DEIMR, dev_priv->saveDEIMR); 853 I915_WRITE(GTIER, dev_priv->saveGTIER); 854 I915_WRITE(GTIMR, dev_priv->saveGTIMR); 855 I915_WRITE(FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR); 856 I915_WRITE(FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR); 857 } else { 858 I915_WRITE (IER, dev_priv->saveIER); 859 I915_WRITE (IMR, dev_priv->saveIMR); 860 } 861 862 /* Clock gating state */ 863 intel_init_clock_gating(dev); 864 865 if (HAS_PCH_SPLIT(dev)) { 866 ironlake_enable_drps(dev); 867 intel_init_emon(dev); 868 } 869 870 /* Cache mode state */ 871 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); 872 873 /* Memory arbitration state */ 874 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); 875 876 for (i = 0; i < 16; i++) { 877 I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); 878 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i]); 879 } 880 for (i = 0; i < 3; i++) 881 I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); 882 883 intel_i2c_reset(dev); 884 885 return 0; 886 } 887