1 /* $OpenBSD: i915_suspend.c,v 1.7 2015/09/23 23:12:12 kettenis Exp $ */ 2 /* 3 * 4 * Copyright 2008 (c) Intel Corporation 5 * Jesse Barnes <jbarnes@virtuousgeek.org> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 */ 27 28 #include <dev/pci/drm/drmP.h> 29 #include <dev/pci/drm/i915_drm.h> 30 #include "intel_drv.h" 31 #include "i915_reg.h" 32 33 static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) 34 { 35 struct drm_i915_private *dev_priv = dev->dev_private; 36 37 I915_WRITE8(index_port, reg); 38 return I915_READ8(data_port); 39 } 40 41 static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) 42 { 43 struct drm_i915_private *dev_priv = dev->dev_private; 44 45 I915_READ8(st01); 46 I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); 47 return I915_READ8(VGA_AR_DATA_READ); 48 } 49 50 static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) 51 { 52 struct drm_i915_private *dev_priv = dev->dev_private; 53 54 I915_READ8(st01); 55 I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); 56 I915_WRITE8(VGA_AR_DATA_WRITE, val); 57 } 58 59 static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) 60 { 61 struct drm_i915_private *dev_priv = dev->dev_private; 62 63 I915_WRITE8(index_port, reg); 64 I915_WRITE8(data_port, val); 65 } 66 67 static void i915_save_vga(struct drm_device *dev) 68 { 69 struct drm_i915_private *dev_priv = dev->dev_private; 70 int i; 71 u16 cr_index, cr_data, st01; 72 73 /* VGA state */ 74 dev_priv->regfile.saveVGA0 = I915_READ(VGA0); 75 dev_priv->regfile.saveVGA1 = I915_READ(VGA1); 76 dev_priv->regfile.saveVGA_PD = I915_READ(VGA_PD); 77 dev_priv->regfile.saveVGACNTRL = I915_READ(i915_vgacntrl_reg(dev)); 78 79 /* VGA color palette registers */ 80 dev_priv->regfile.saveDACMASK = I915_READ8(VGA_DACMASK); 81 82 /* MSR bits */ 83 dev_priv->regfile.saveMSR = I915_READ8(VGA_MSR_READ); 84 if (dev_priv->regfile.saveMSR & VGA_MSR_CGA_MODE) { 85 cr_index = VGA_CR_INDEX_CGA; 86 cr_data = VGA_CR_DATA_CGA; 87 st01 = VGA_ST01_CGA; 88 } else { 89 cr_index = VGA_CR_INDEX_MDA; 90 cr_data = VGA_CR_DATA_MDA; 91 st01 = VGA_ST01_MDA; 92 } 93 94 /* CRT controller regs */ 95 i915_write_indexed(dev, cr_index, cr_data, 0x11, 96 i915_read_indexed(dev, cr_index, cr_data, 0x11) & 97 (~0x80)); 98 for (i = 0; i <= 0x24; i++) 99 dev_priv->regfile.saveCR[i] = 100 i915_read_indexed(dev, cr_index, cr_data, i); 101 /* Make sure we don't turn off CR group 0 writes */ 102 dev_priv->regfile.saveCR[0x11] &= ~0x80; 103 104 /* Attribute controller registers */ 105 I915_READ8(st01); 106 dev_priv->regfile.saveAR_INDEX = I915_READ8(VGA_AR_INDEX); 107 for (i = 0; i <= 0x14; i++) 108 dev_priv->regfile.saveAR[i] = i915_read_ar(dev, st01, i, 0); 109 I915_READ8(st01); 110 I915_WRITE8(VGA_AR_INDEX, dev_priv->regfile.saveAR_INDEX); 111 I915_READ8(st01); 112 113 /* Graphics controller registers */ 114 for (i = 0; i < 9; i++) 115 dev_priv->regfile.saveGR[i] = 116 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i); 117 118 dev_priv->regfile.saveGR[0x10] = 119 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10); 120 dev_priv->regfile.saveGR[0x11] = 121 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11); 122 dev_priv->regfile.saveGR[0x18] = 123 i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18); 124 125 /* Sequencer registers */ 126 for (i = 0; i < 8; i++) 127 dev_priv->regfile.saveSR[i] = 128 i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i); 129 } 130 131 static void i915_restore_vga(struct drm_device *dev) 132 { 133 struct drm_i915_private *dev_priv = dev->dev_private; 134 int i; 135 u16 cr_index, cr_data, st01; 136 137 /* VGA state */ 138 I915_WRITE(i915_vgacntrl_reg(dev), dev_priv->regfile.saveVGACNTRL); 139 140 I915_WRITE(VGA0, dev_priv->regfile.saveVGA0); 141 I915_WRITE(VGA1, dev_priv->regfile.saveVGA1); 142 I915_WRITE(VGA_PD, dev_priv->regfile.saveVGA_PD); 143 POSTING_READ(VGA_PD); 144 udelay(150); 145 146 /* MSR bits */ 147 I915_WRITE8(VGA_MSR_WRITE, dev_priv->regfile.saveMSR); 148 if (dev_priv->regfile.saveMSR & VGA_MSR_CGA_MODE) { 149 cr_index = VGA_CR_INDEX_CGA; 150 cr_data = VGA_CR_DATA_CGA; 151 st01 = VGA_ST01_CGA; 152 } else { 153 cr_index = VGA_CR_INDEX_MDA; 154 cr_data = VGA_CR_DATA_MDA; 155 st01 = VGA_ST01_MDA; 156 } 157 158 /* Sequencer registers, don't write SR07 */ 159 for (i = 0; i < 7; i++) 160 i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i, 161 dev_priv->regfile.saveSR[i]); 162 163 /* CRT controller regs */ 164 /* Enable CR group 0 writes */ 165 i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->regfile.saveCR[0x11]); 166 for (i = 0; i <= 0x24; i++) 167 i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->regfile.saveCR[i]); 168 169 /* Graphics controller regs */ 170 for (i = 0; i < 9; i++) 171 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i, 172 dev_priv->regfile.saveGR[i]); 173 174 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10, 175 dev_priv->regfile.saveGR[0x10]); 176 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11, 177 dev_priv->regfile.saveGR[0x11]); 178 i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18, 179 dev_priv->regfile.saveGR[0x18]); 180 181 /* Attribute controller registers */ 182 I915_READ8(st01); /* switch back to index mode */ 183 for (i = 0; i <= 0x14; i++) 184 i915_write_ar(dev, st01, i, dev_priv->regfile.saveAR[i], 0); 185 I915_READ8(st01); /* switch back to index mode */ 186 I915_WRITE8(VGA_AR_INDEX, dev_priv->regfile.saveAR_INDEX | 0x20); 187 I915_READ8(st01); 188 189 /* VGA color palette registers */ 190 I915_WRITE8(VGA_DACMASK, dev_priv->regfile.saveDACMASK); 191 } 192 193 static void i915_save_display(struct drm_device *dev) 194 { 195 struct drm_i915_private *dev_priv = dev->dev_private; 196 197 /* Display arbitration control */ 198 if (INTEL_INFO(dev)->gen <= 4) 199 dev_priv->regfile.saveDSPARB = I915_READ(DSPARB); 200 201 /* This is only meaningful in non-KMS mode */ 202 /* Don't regfile.save them in KMS mode */ 203 #ifdef __linux__ 204 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 205 i915_save_display_reg(dev); 206 #endif 207 208 /* LVDS state */ 209 if (HAS_PCH_SPLIT(dev)) { 210 dev_priv->regfile.savePP_CONTROL = I915_READ(PCH_PP_CONTROL); 211 if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) 212 dev_priv->regfile.saveLVDS = I915_READ(PCH_LVDS); 213 } else if (IS_VALLEYVIEW(dev)) { 214 dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); 215 dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); 216 217 dev_priv->regfile.saveBLC_HIST_CTL = 218 I915_READ(VLV_BLC_HIST_CTL(PIPE_A)); 219 dev_priv->regfile.saveBLC_HIST_CTL_B = 220 I915_READ(VLV_BLC_HIST_CTL(PIPE_B)); 221 } else { 222 dev_priv->regfile.savePP_CONTROL = I915_READ(PP_CONTROL); 223 dev_priv->regfile.savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); 224 dev_priv->regfile.saveBLC_HIST_CTL = I915_READ(BLC_HIST_CTL); 225 if (IS_MOBILE(dev) && !IS_I830(dev)) 226 dev_priv->regfile.saveLVDS = I915_READ(LVDS); 227 } 228 229 if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) 230 dev_priv->regfile.savePFIT_CONTROL = I915_READ(PFIT_CONTROL); 231 232 if (HAS_PCH_SPLIT(dev)) { 233 dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); 234 dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); 235 dev_priv->regfile.savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); 236 } else { 237 dev_priv->regfile.savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); 238 dev_priv->regfile.savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); 239 dev_priv->regfile.savePP_DIVISOR = I915_READ(PP_DIVISOR); 240 } 241 242 /* Only regfile.save FBC state on the platform that supports FBC */ 243 if (HAS_FBC(dev)) { 244 if (HAS_PCH_SPLIT(dev)) { 245 dev_priv->regfile.saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); 246 } else if (IS_GM45(dev)) { 247 dev_priv->regfile.saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); 248 } else { 249 dev_priv->regfile.saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); 250 dev_priv->regfile.saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); 251 dev_priv->regfile.saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); 252 dev_priv->regfile.saveFBC_CONTROL = I915_READ(FBC_CONTROL); 253 } 254 } 255 256 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 257 i915_save_vga(dev); 258 } 259 260 static void i915_restore_display(struct drm_device *dev) 261 { 262 struct drm_i915_private *dev_priv = dev->dev_private; 263 u32 mask = 0xffffffff; 264 265 /* Display arbitration */ 266 if (INTEL_INFO(dev)->gen <= 4) 267 I915_WRITE(DSPARB, dev_priv->regfile.saveDSPARB); 268 269 #ifdef __linux__ 270 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 271 i915_restore_display_reg(dev); 272 #endif 273 274 if (drm_core_check_feature(dev, DRIVER_MODESET)) 275 mask = ~LVDS_PORT_EN; 276 277 if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) 278 I915_WRITE(PCH_LVDS, dev_priv->regfile.saveLVDS & mask); 279 else if (INTEL_INFO(dev)->gen <= 4 && IS_MOBILE(dev) && !IS_I830(dev)) 280 I915_WRITE(LVDS, dev_priv->regfile.saveLVDS & mask); 281 282 if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) 283 I915_WRITE(PFIT_CONTROL, dev_priv->regfile.savePFIT_CONTROL); 284 285 if (HAS_PCH_SPLIT(dev)) { 286 I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS); 287 I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); 288 I915_WRITE(PCH_PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR); 289 I915_WRITE(PCH_PP_CONTROL, dev_priv->regfile.savePP_CONTROL); 290 I915_WRITE(RSTDBYCTL, 291 dev_priv->regfile.saveMCHBAR_RENDER_STANDBY); 292 } else if (IS_VALLEYVIEW(dev)) { 293 I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A), 294 dev_priv->regfile.saveBLC_HIST_CTL); 295 I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B), 296 dev_priv->regfile.saveBLC_HIST_CTL); 297 } else { 298 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->regfile.savePFIT_PGM_RATIOS); 299 I915_WRITE(BLC_HIST_CTL, dev_priv->regfile.saveBLC_HIST_CTL); 300 I915_WRITE(PP_ON_DELAYS, dev_priv->regfile.savePP_ON_DELAYS); 301 I915_WRITE(PP_OFF_DELAYS, dev_priv->regfile.savePP_OFF_DELAYS); 302 I915_WRITE(PP_DIVISOR, dev_priv->regfile.savePP_DIVISOR); 303 I915_WRITE(PP_CONTROL, dev_priv->regfile.savePP_CONTROL); 304 } 305 306 /* only restore FBC info on the platform that supports FBC*/ 307 intel_disable_fbc(dev); 308 if (HAS_FBC(dev)) { 309 if (HAS_PCH_SPLIT(dev)) { 310 I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->regfile.saveDPFC_CB_BASE); 311 } else if (IS_GM45(dev)) { 312 I915_WRITE(DPFC_CB_BASE, dev_priv->regfile.saveDPFC_CB_BASE); 313 } else { 314 I915_WRITE(FBC_CFB_BASE, dev_priv->regfile.saveFBC_CFB_BASE); 315 I915_WRITE(FBC_LL_BASE, dev_priv->regfile.saveFBC_LL_BASE); 316 I915_WRITE(FBC_CONTROL2, dev_priv->regfile.saveFBC_CONTROL2); 317 I915_WRITE(FBC_CONTROL, dev_priv->regfile.saveFBC_CONTROL); 318 } 319 } 320 321 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 322 i915_restore_vga(dev); 323 else 324 i915_redisable_vga(dev); 325 } 326 327 int i915_save_state(struct drm_device *dev) 328 { 329 struct drm_i915_private *dev_priv = dev->dev_private; 330 int i; 331 332 if (INTEL_INFO(dev)->gen <= 4) 333 pci_read_config_byte(dev->pdev, LBB, 334 &dev_priv->regfile.saveLBB); 335 336 mutex_lock(&dev->struct_mutex); 337 338 i915_save_display(dev); 339 340 if (!drm_core_check_feature(dev, DRIVER_MODESET)) { 341 /* Interrupt state */ 342 if (HAS_PCH_SPLIT(dev)) { 343 dev_priv->regfile.saveDEIER = I915_READ(DEIER); 344 dev_priv->regfile.saveDEIMR = I915_READ(DEIMR); 345 dev_priv->regfile.saveGTIER = I915_READ(GTIER); 346 dev_priv->regfile.saveGTIMR = I915_READ(GTIMR); 347 dev_priv->regfile.saveFDI_RXA_IMR = I915_READ(_FDI_RXA_IMR); 348 dev_priv->regfile.saveFDI_RXB_IMR = I915_READ(_FDI_RXB_IMR); 349 dev_priv->regfile.saveMCHBAR_RENDER_STANDBY = 350 I915_READ(RSTDBYCTL); 351 dev_priv->regfile.savePCH_PORT_HOTPLUG = I915_READ(PCH_PORT_HOTPLUG); 352 } else { 353 dev_priv->regfile.saveIER = I915_READ(IER); 354 dev_priv->regfile.saveIMR = I915_READ(IMR); 355 } 356 } 357 358 intel_disable_gt_powersave(dev); 359 360 /* Cache mode state */ 361 if (INTEL_INFO(dev)->gen < 7) 362 dev_priv->regfile.saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); 363 364 /* Memory Arbitration state */ 365 dev_priv->regfile.saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); 366 367 /* Scratch space */ 368 for (i = 0; i < 16; i++) { 369 dev_priv->regfile.saveSWF0[i] = I915_READ(SWF00 + (i << 2)); 370 dev_priv->regfile.saveSWF1[i] = I915_READ(SWF10 + (i << 2)); 371 } 372 for (i = 0; i < 3; i++) 373 dev_priv->regfile.saveSWF2[i] = I915_READ(SWF30 + (i << 2)); 374 375 mutex_unlock(&dev->struct_mutex); 376 377 return 0; 378 } 379 380 int i915_restore_state(struct drm_device *dev) 381 { 382 struct drm_i915_private *dev_priv = dev->dev_private; 383 int i; 384 385 if (INTEL_INFO(dev)->gen <= 4) 386 pci_write_config_byte(dev->pdev, LBB, 387 dev_priv->regfile.saveLBB); 388 389 mutex_lock(&dev->struct_mutex); 390 391 i915_gem_restore_fences(dev); 392 i915_restore_display(dev); 393 394 if (!drm_core_check_feature(dev, DRIVER_MODESET)) { 395 /* Interrupt state */ 396 if (HAS_PCH_SPLIT(dev)) { 397 I915_WRITE(DEIER, dev_priv->regfile.saveDEIER); 398 I915_WRITE(DEIMR, dev_priv->regfile.saveDEIMR); 399 I915_WRITE(GTIER, dev_priv->regfile.saveGTIER); 400 I915_WRITE(GTIMR, dev_priv->regfile.saveGTIMR); 401 I915_WRITE(_FDI_RXA_IMR, dev_priv->regfile.saveFDI_RXA_IMR); 402 I915_WRITE(_FDI_RXB_IMR, dev_priv->regfile.saveFDI_RXB_IMR); 403 I915_WRITE(PCH_PORT_HOTPLUG, dev_priv->regfile.savePCH_PORT_HOTPLUG); 404 } else { 405 I915_WRITE(IER, dev_priv->regfile.saveIER); 406 I915_WRITE(IMR, dev_priv->regfile.saveIMR); 407 } 408 } 409 410 /* Cache mode state */ 411 if (INTEL_INFO(dev)->gen < 7) 412 I915_WRITE(CACHE_MODE_0, dev_priv->regfile.saveCACHE_MODE_0 | 413 0xffff0000); 414 415 /* Memory arbitration state */ 416 I915_WRITE(MI_ARB_STATE, dev_priv->regfile.saveMI_ARB_STATE | 0xffff0000); 417 418 for (i = 0; i < 16; i++) { 419 I915_WRITE(SWF00 + (i << 2), dev_priv->regfile.saveSWF0[i]); 420 I915_WRITE(SWF10 + (i << 2), dev_priv->regfile.saveSWF1[i]); 421 } 422 for (i = 0; i < 3; i++) 423 I915_WRITE(SWF30 + (i << 2), dev_priv->regfile.saveSWF2[i]); 424 425 mutex_unlock(&dev->struct_mutex); 426 427 intel_i2c_reset(dev); 428 429 return 0; 430 } 431