3 * Copyright 2008 (c) Intel Corporation
4 * Jesse Barnes <jbarnes@virtuousgeek.org>
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
28 #include <drm/i915_drm.h>
29 #include "intel_drv.h"
32 static u8
i915_read_indexed(struct drm_device
*dev
, u16 index_port
, u16 data_port
, u8 reg
)
34 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
36 I915_WRITE8(index_port
, reg
);
37 return I915_READ8(data_port
);
40 static u8
i915_read_ar(struct drm_device
*dev
, u16 st01
, u8 reg
, u16 palette_enable
)
42 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
45 I915_WRITE8(VGA_AR_INDEX
, palette_enable
| reg
);
46 return I915_READ8(VGA_AR_DATA_READ
);
49 static void i915_write_ar(struct drm_device
*dev
, u16 st01
, u8 reg
, u8 val
, u16 palette_enable
)
51 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
54 I915_WRITE8(VGA_AR_INDEX
, palette_enable
| reg
);
55 I915_WRITE8(VGA_AR_DATA_WRITE
, val
);
58 static void i915_write_indexed(struct drm_device
*dev
, u16 index_port
, u16 data_port
, u8 reg
, u8 val
)
60 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
62 I915_WRITE8(index_port
, reg
);
63 I915_WRITE8(data_port
, val
);
66 static void i915_save_vga(struct drm_device
*dev
)
68 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
70 u16 cr_index
, cr_data
, st01
;
73 dev_priv
->regfile
.saveVGA0
= I915_READ(VGA0
);
74 dev_priv
->regfile
.saveVGA1
= I915_READ(VGA1
);
75 dev_priv
->regfile
.saveVGA_PD
= I915_READ(VGA_PD
);
76 dev_priv
->regfile
.saveVGACNTRL
= I915_READ(i915_vgacntrl_reg(dev
));
78 /* VGA color palette registers */
79 dev_priv
->regfile
.saveDACMASK
= I915_READ8(VGA_DACMASK
);
82 dev_priv
->regfile
.saveMSR
= I915_READ8(VGA_MSR_READ
);
83 if (dev_priv
->regfile
.saveMSR
& VGA_MSR_CGA_MODE
) {
84 cr_index
= VGA_CR_INDEX_CGA
;
85 cr_data
= VGA_CR_DATA_CGA
;
88 cr_index
= VGA_CR_INDEX_MDA
;
89 cr_data
= VGA_CR_DATA_MDA
;
93 /* CRT controller regs */
94 i915_write_indexed(dev
, cr_index
, cr_data
, 0x11,
95 i915_read_indexed(dev
, cr_index
, cr_data
, 0x11) &
97 for (i
= 0; i
<= 0x24; i
++)
98 dev_priv
->regfile
.saveCR
[i
] =
99 i915_read_indexed(dev
, cr_index
, cr_data
, i
);
100 /* Make sure we don't turn off CR group 0 writes */
101 dev_priv
->regfile
.saveCR
[0x11] &= ~0x80;
103 /* Attribute controller registers */
105 dev_priv
->regfile
.saveAR_INDEX
= I915_READ8(VGA_AR_INDEX
);
106 for (i
= 0; i
<= 0x14; i
++)
107 dev_priv
->regfile
.saveAR
[i
] = i915_read_ar(dev
, st01
, i
, 0);
109 I915_WRITE8(VGA_AR_INDEX
, dev_priv
->regfile
.saveAR_INDEX
);
112 /* Graphics controller registers */
113 for (i
= 0; i
< 9; i
++)
114 dev_priv
->regfile
.saveGR
[i
] =
115 i915_read_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, i
);
117 dev_priv
->regfile
.saveGR
[0x10] =
118 i915_read_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, 0x10);
119 dev_priv
->regfile
.saveGR
[0x11] =
120 i915_read_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, 0x11);
121 dev_priv
->regfile
.saveGR
[0x18] =
122 i915_read_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, 0x18);
124 /* Sequencer registers */
125 for (i
= 0; i
< 8; i
++)
126 dev_priv
->regfile
.saveSR
[i
] =
127 i915_read_indexed(dev
, VGA_SR_INDEX
, VGA_SR_DATA
, i
);
130 static void i915_restore_vga(struct drm_device
*dev
)
132 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
134 u16 cr_index
, cr_data
, st01
;
137 I915_WRITE(i915_vgacntrl_reg(dev
), dev_priv
->regfile
.saveVGACNTRL
);
139 I915_WRITE(VGA0
, dev_priv
->regfile
.saveVGA0
);
140 I915_WRITE(VGA1
, dev_priv
->regfile
.saveVGA1
);
141 I915_WRITE(VGA_PD
, dev_priv
->regfile
.saveVGA_PD
);
142 POSTING_READ(VGA_PD
);
146 I915_WRITE8(VGA_MSR_WRITE
, dev_priv
->regfile
.saveMSR
);
147 if (dev_priv
->regfile
.saveMSR
& VGA_MSR_CGA_MODE
) {
148 cr_index
= VGA_CR_INDEX_CGA
;
149 cr_data
= VGA_CR_DATA_CGA
;
152 cr_index
= VGA_CR_INDEX_MDA
;
153 cr_data
= VGA_CR_DATA_MDA
;
157 /* Sequencer registers, don't write SR07 */
158 for (i
= 0; i
< 7; i
++)
159 i915_write_indexed(dev
, VGA_SR_INDEX
, VGA_SR_DATA
, i
,
160 dev_priv
->regfile
.saveSR
[i
]);
162 /* CRT controller regs */
163 /* Enable CR group 0 writes */
164 i915_write_indexed(dev
, cr_index
, cr_data
, 0x11, dev_priv
->regfile
.saveCR
[0x11]);
165 for (i
= 0; i
<= 0x24; i
++)
166 i915_write_indexed(dev
, cr_index
, cr_data
, i
, dev_priv
->regfile
.saveCR
[i
]);
168 /* Graphics controller regs */
169 for (i
= 0; i
< 9; i
++)
170 i915_write_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, i
,
171 dev_priv
->regfile
.saveGR
[i
]);
173 i915_write_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, 0x10,
174 dev_priv
->regfile
.saveGR
[0x10]);
175 i915_write_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, 0x11,
176 dev_priv
->regfile
.saveGR
[0x11]);
177 i915_write_indexed(dev
, VGA_GR_INDEX
, VGA_GR_DATA
, 0x18,
178 dev_priv
->regfile
.saveGR
[0x18]);
180 /* Attribute controller registers */
181 I915_READ8(st01
); /* switch back to index mode */
182 for (i
= 0; i
<= 0x14; i
++)
183 i915_write_ar(dev
, st01
, i
, dev_priv
->regfile
.saveAR
[i
], 0);
184 I915_READ8(st01
); /* switch back to index mode */
185 I915_WRITE8(VGA_AR_INDEX
, dev_priv
->regfile
.saveAR_INDEX
| 0x20);
188 /* VGA color palette registers */
189 I915_WRITE8(VGA_DACMASK
, dev_priv
->regfile
.saveDACMASK
);
192 static void i915_save_display(struct drm_device
*dev
)
194 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
197 /* Display arbitration control */
198 if (INTEL_INFO(dev
)->gen
<= 4)
199 dev_priv
->regfile
.saveDSPARB
= I915_READ(DSPARB
);
201 /* This is only meaningful in non-KMS mode */
202 /* Don't regfile.save them in KMS mode */
203 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
204 i915_save_display_reg(dev
);
206 spin_lock_irqsave(&dev_priv
->backlight
.lock
, flags
);
209 if (HAS_PCH_SPLIT(dev
)) {
210 dev_priv
->regfile
.savePP_CONTROL
= I915_READ(PCH_PP_CONTROL
);
211 dev_priv
->regfile
.saveBLC_PWM_CTL
= I915_READ(BLC_PWM_PCH_CTL1
);
212 dev_priv
->regfile
.saveBLC_PWM_CTL2
= I915_READ(BLC_PWM_PCH_CTL2
);
213 dev_priv
->regfile
.saveBLC_CPU_PWM_CTL
= I915_READ(BLC_PWM_CPU_CTL
);
214 dev_priv
->regfile
.saveBLC_CPU_PWM_CTL2
= I915_READ(BLC_PWM_CPU_CTL2
);
215 if (HAS_PCH_IBX(dev
) || HAS_PCH_CPT(dev
))
216 dev_priv
->regfile
.saveLVDS
= I915_READ(PCH_LVDS
);
218 dev_priv
->regfile
.savePP_CONTROL
= I915_READ(PP_CONTROL
);
219 dev_priv
->regfile
.savePFIT_PGM_RATIOS
= I915_READ(PFIT_PGM_RATIOS
);
220 dev_priv
->regfile
.saveBLC_PWM_CTL
= I915_READ(BLC_PWM_CTL
);
221 dev_priv
->regfile
.saveBLC_HIST_CTL
= I915_READ(BLC_HIST_CTL
);
222 if (INTEL_INFO(dev
)->gen
>= 4)
223 dev_priv
->regfile
.saveBLC_PWM_CTL2
= I915_READ(BLC_PWM_CTL2
);
224 if (IS_MOBILE(dev
) && !IS_I830(dev
))
225 dev_priv
->regfile
.saveLVDS
= I915_READ(LVDS
);
228 spin_unlock_irqrestore(&dev_priv
->backlight
.lock
, flags
);
230 if (!IS_I830(dev
) && !IS_845G(dev
) && !HAS_PCH_SPLIT(dev
))
231 dev_priv
->regfile
.savePFIT_CONTROL
= I915_READ(PFIT_CONTROL
);
233 if (HAS_PCH_SPLIT(dev
)) {
234 dev_priv
->regfile
.savePP_ON_DELAYS
= I915_READ(PCH_PP_ON_DELAYS
);
235 dev_priv
->regfile
.savePP_OFF_DELAYS
= I915_READ(PCH_PP_OFF_DELAYS
);
236 dev_priv
->regfile
.savePP_DIVISOR
= I915_READ(PCH_PP_DIVISOR
);
238 dev_priv
->regfile
.savePP_ON_DELAYS
= I915_READ(PP_ON_DELAYS
);
239 dev_priv
->regfile
.savePP_OFF_DELAYS
= I915_READ(PP_OFF_DELAYS
);
240 dev_priv
->regfile
.savePP_DIVISOR
= I915_READ(PP_DIVISOR
);
243 /* Only regfile.save FBC state on the platform that supports FBC */
244 if (I915_HAS_FBC(dev
)) {
245 if (HAS_PCH_SPLIT(dev
)) {
246 dev_priv
->regfile
.saveDPFC_CB_BASE
= I915_READ(ILK_DPFC_CB_BASE
);
247 } else if (IS_GM45(dev
)) {
248 dev_priv
->regfile
.saveDPFC_CB_BASE
= I915_READ(DPFC_CB_BASE
);
250 dev_priv
->regfile
.saveFBC_CFB_BASE
= I915_READ(FBC_CFB_BASE
);
251 dev_priv
->regfile
.saveFBC_LL_BASE
= I915_READ(FBC_LL_BASE
);
252 dev_priv
->regfile
.saveFBC_CONTROL2
= I915_READ(FBC_CONTROL2
);
253 dev_priv
->regfile
.saveFBC_CONTROL
= I915_READ(FBC_CONTROL
);
257 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
261 static void i915_restore_display(struct drm_device
*dev
)
263 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
264 u32 mask
= 0xffffffff;
267 /* Display arbitration */
268 if (INTEL_INFO(dev
)->gen
<= 4)
269 I915_WRITE(DSPARB
, dev_priv
->regfile
.saveDSPARB
);
271 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
272 i915_restore_display_reg(dev
);
274 spin_lock_irqsave(&dev_priv
->backlight
.lock
, flags
);
277 if (INTEL_INFO(dev
)->gen
>= 4 && !HAS_PCH_SPLIT(dev
))
278 I915_WRITE(BLC_PWM_CTL2
, dev_priv
->regfile
.saveBLC_PWM_CTL2
);
280 if (drm_core_check_feature(dev
, DRIVER_MODESET
))
281 mask
= ~LVDS_PORT_EN
;
283 if (HAS_PCH_IBX(dev
) || HAS_PCH_CPT(dev
))
284 I915_WRITE(PCH_LVDS
, dev_priv
->regfile
.saveLVDS
& mask
);
285 else if (INTEL_INFO(dev
)->gen
<= 4 && IS_MOBILE(dev
) && !IS_I830(dev
))
286 I915_WRITE(LVDS
, dev_priv
->regfile
.saveLVDS
& mask
);
288 if (!IS_I830(dev
) && !IS_845G(dev
) && !HAS_PCH_SPLIT(dev
))
289 I915_WRITE(PFIT_CONTROL
, dev_priv
->regfile
.savePFIT_CONTROL
);
291 if (HAS_PCH_SPLIT(dev
)) {
292 I915_WRITE(BLC_PWM_PCH_CTL1
, dev_priv
->regfile
.saveBLC_PWM_CTL
);
293 I915_WRITE(BLC_PWM_PCH_CTL2
, dev_priv
->regfile
.saveBLC_PWM_CTL2
);
294 /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2;
295 * otherwise we get blank eDP screen after S3 on some machines
297 I915_WRITE(BLC_PWM_CPU_CTL2
, dev_priv
->regfile
.saveBLC_CPU_PWM_CTL2
);
298 I915_WRITE(BLC_PWM_CPU_CTL
, dev_priv
->regfile
.saveBLC_CPU_PWM_CTL
);
299 I915_WRITE(PCH_PP_ON_DELAYS
, dev_priv
->regfile
.savePP_ON_DELAYS
);
300 I915_WRITE(PCH_PP_OFF_DELAYS
, dev_priv
->regfile
.savePP_OFF_DELAYS
);
301 I915_WRITE(PCH_PP_DIVISOR
, dev_priv
->regfile
.savePP_DIVISOR
);
302 I915_WRITE(PCH_PP_CONTROL
, dev_priv
->regfile
.savePP_CONTROL
);
303 I915_WRITE(RSTDBYCTL
,
304 dev_priv
->regfile
.saveMCHBAR_RENDER_STANDBY
);
306 I915_WRITE(PFIT_PGM_RATIOS
, dev_priv
->regfile
.savePFIT_PGM_RATIOS
);
307 I915_WRITE(BLC_PWM_CTL
, dev_priv
->regfile
.saveBLC_PWM_CTL
);
308 I915_WRITE(BLC_HIST_CTL
, dev_priv
->regfile
.saveBLC_HIST_CTL
);
309 I915_WRITE(PP_ON_DELAYS
, dev_priv
->regfile
.savePP_ON_DELAYS
);
310 I915_WRITE(PP_OFF_DELAYS
, dev_priv
->regfile
.savePP_OFF_DELAYS
);
311 I915_WRITE(PP_DIVISOR
, dev_priv
->regfile
.savePP_DIVISOR
);
312 I915_WRITE(PP_CONTROL
, dev_priv
->regfile
.savePP_CONTROL
);
315 spin_unlock_irqrestore(&dev_priv
->backlight
.lock
, flags
);
317 /* only restore FBC info on the platform that supports FBC*/
318 intel_disable_fbc(dev
);
319 if (I915_HAS_FBC(dev
)) {
320 if (HAS_PCH_SPLIT(dev
)) {
321 I915_WRITE(ILK_DPFC_CB_BASE
, dev_priv
->regfile
.saveDPFC_CB_BASE
);
322 } else if (IS_GM45(dev
)) {
323 I915_WRITE(DPFC_CB_BASE
, dev_priv
->regfile
.saveDPFC_CB_BASE
);
325 I915_WRITE(FBC_CFB_BASE
, dev_priv
->regfile
.saveFBC_CFB_BASE
);
326 I915_WRITE(FBC_LL_BASE
, dev_priv
->regfile
.saveFBC_LL_BASE
);
327 I915_WRITE(FBC_CONTROL2
, dev_priv
->regfile
.saveFBC_CONTROL2
);
328 I915_WRITE(FBC_CONTROL
, dev_priv
->regfile
.saveFBC_CONTROL
);
332 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
333 i915_restore_vga(dev
);
335 i915_redisable_vga(dev
);
338 int i915_save_state(struct drm_device
*dev
)
340 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
343 pci_read_config_byte(dev
->pdev
, LBB
, &dev_priv
->regfile
.saveLBB
);
345 mutex_lock(&dev
->struct_mutex
);
347 i915_save_display(dev
);
349 if (!drm_core_check_feature(dev
, DRIVER_MODESET
)) {
350 /* Interrupt state */
351 if (HAS_PCH_SPLIT(dev
)) {
352 dev_priv
->regfile
.saveDEIER
= I915_READ(DEIER
);
353 dev_priv
->regfile
.saveDEIMR
= I915_READ(DEIMR
);
354 dev_priv
->regfile
.saveGTIER
= I915_READ(GTIER
);
355 dev_priv
->regfile
.saveGTIMR
= I915_READ(GTIMR
);
356 dev_priv
->regfile
.saveFDI_RXA_IMR
= I915_READ(_FDI_RXA_IMR
);
357 dev_priv
->regfile
.saveFDI_RXB_IMR
= I915_READ(_FDI_RXB_IMR
);
358 dev_priv
->regfile
.saveMCHBAR_RENDER_STANDBY
=
359 I915_READ(RSTDBYCTL
);
360 dev_priv
->regfile
.savePCH_PORT_HOTPLUG
= I915_READ(PCH_PORT_HOTPLUG
);
362 dev_priv
->regfile
.saveIER
= I915_READ(IER
);
363 dev_priv
->regfile
.saveIMR
= I915_READ(IMR
);
367 intel_disable_gt_powersave(dev
);
369 /* Cache mode state */
370 dev_priv
->regfile
.saveCACHE_MODE_0
= I915_READ(CACHE_MODE_0
);
372 /* Memory Arbitration state */
373 dev_priv
->regfile
.saveMI_ARB_STATE
= I915_READ(MI_ARB_STATE
);
376 for (i
= 0; i
< 16; i
++) {
377 dev_priv
->regfile
.saveSWF0
[i
] = I915_READ(SWF00
+ (i
<< 2));
378 dev_priv
->regfile
.saveSWF1
[i
] = I915_READ(SWF10
+ (i
<< 2));
380 for (i
= 0; i
< 3; i
++)
381 dev_priv
->regfile
.saveSWF2
[i
] = I915_READ(SWF30
+ (i
<< 2));
383 mutex_unlock(&dev
->struct_mutex
);
388 int i915_restore_state(struct drm_device
*dev
)
390 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
393 pci_write_config_byte(dev
->pdev
, LBB
, dev_priv
->regfile
.saveLBB
);
395 mutex_lock(&dev
->struct_mutex
);
397 i915_gem_restore_fences(dev
);
398 i915_restore_display(dev
);
400 if (!drm_core_check_feature(dev
, DRIVER_MODESET
)) {
401 /* Interrupt state */
402 if (HAS_PCH_SPLIT(dev
)) {
403 I915_WRITE(DEIER
, dev_priv
->regfile
.saveDEIER
);
404 I915_WRITE(DEIMR
, dev_priv
->regfile
.saveDEIMR
);
405 I915_WRITE(GTIER
, dev_priv
->regfile
.saveGTIER
);
406 I915_WRITE(GTIMR
, dev_priv
->regfile
.saveGTIMR
);
407 I915_WRITE(_FDI_RXA_IMR
, dev_priv
->regfile
.saveFDI_RXA_IMR
);
408 I915_WRITE(_FDI_RXB_IMR
, dev_priv
->regfile
.saveFDI_RXB_IMR
);
409 I915_WRITE(PCH_PORT_HOTPLUG
, dev_priv
->regfile
.savePCH_PORT_HOTPLUG
);
411 I915_WRITE(IER
, dev_priv
->regfile
.saveIER
);
412 I915_WRITE(IMR
, dev_priv
->regfile
.saveIMR
);
416 /* Cache mode state */
417 I915_WRITE(CACHE_MODE_0
, dev_priv
->regfile
.saveCACHE_MODE_0
| 0xffff0000);
419 /* Memory arbitration state */
420 I915_WRITE(MI_ARB_STATE
, dev_priv
->regfile
.saveMI_ARB_STATE
| 0xffff0000);
422 for (i
= 0; i
< 16; i
++) {
423 I915_WRITE(SWF00
+ (i
<< 2), dev_priv
->regfile
.saveSWF0
[i
]);
424 I915_WRITE(SWF10
+ (i
<< 2), dev_priv
->regfile
.saveSWF1
[i
]);
426 for (i
= 0; i
< 3; i
++)
427 I915_WRITE(SWF30
+ (i
<< 2), dev_priv
->regfile
.saveSWF2
[i
]);
429 mutex_unlock(&dev
->struct_mutex
);
431 intel_i2c_reset(dev
);