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
;
196 /* Display arbitration control */
197 if (INTEL_INFO(dev
)->gen
<= 4)
198 dev_priv
->regfile
.saveDSPARB
= I915_READ(DSPARB
);
200 /* This is only meaningful in non-KMS mode */
201 /* Don't regfile.save them in KMS mode */
202 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
203 i915_save_display_reg(dev
);
206 if (HAS_PCH_IBX(dev
) || HAS_PCH_CPT(dev
))
207 dev_priv
->regfile
.saveLVDS
= I915_READ(PCH_LVDS
);
208 else if (INTEL_INFO(dev
)->gen
<= 4 && IS_MOBILE(dev
) && !IS_I830(dev
))
209 dev_priv
->regfile
.saveLVDS
= I915_READ(LVDS
);
211 /* Panel power sequencer */
212 if (HAS_PCH_SPLIT(dev
)) {
213 dev_priv
->regfile
.savePP_CONTROL
= I915_READ(PCH_PP_CONTROL
);
214 dev_priv
->regfile
.savePP_ON_DELAYS
= I915_READ(PCH_PP_ON_DELAYS
);
215 dev_priv
->regfile
.savePP_OFF_DELAYS
= I915_READ(PCH_PP_OFF_DELAYS
);
216 dev_priv
->regfile
.savePP_DIVISOR
= I915_READ(PCH_PP_DIVISOR
);
217 } else if (!IS_VALLEYVIEW(dev
)) {
218 dev_priv
->regfile
.savePP_CONTROL
= I915_READ(PP_CONTROL
);
219 dev_priv
->regfile
.savePP_ON_DELAYS
= I915_READ(PP_ON_DELAYS
);
220 dev_priv
->regfile
.savePP_OFF_DELAYS
= I915_READ(PP_OFF_DELAYS
);
221 dev_priv
->regfile
.savePP_DIVISOR
= I915_READ(PP_DIVISOR
);
224 /* save FBC interval */
225 if (HAS_FBC(dev
) && INTEL_INFO(dev
)->gen
<= 4 && !IS_G4X(dev
))
226 dev_priv
->regfile
.saveFBC_CONTROL
= I915_READ(FBC_CONTROL
);
228 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
232 static void i915_restore_display(struct drm_device
*dev
)
234 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
235 u32 mask
= 0xffffffff;
237 /* Display arbitration */
238 if (INTEL_INFO(dev
)->gen
<= 4)
239 I915_WRITE(DSPARB
, dev_priv
->regfile
.saveDSPARB
);
241 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
242 i915_restore_display_reg(dev
);
244 if (drm_core_check_feature(dev
, DRIVER_MODESET
))
245 mask
= ~LVDS_PORT_EN
;
248 if (HAS_PCH_IBX(dev
) || HAS_PCH_CPT(dev
))
249 I915_WRITE(PCH_LVDS
, dev_priv
->regfile
.saveLVDS
& mask
);
250 else if (INTEL_INFO(dev
)->gen
<= 4 && IS_MOBILE(dev
) && !IS_I830(dev
))
251 I915_WRITE(LVDS
, dev_priv
->regfile
.saveLVDS
& mask
);
253 /* Panel power sequencer */
254 if (HAS_PCH_SPLIT(dev
)) {
255 I915_WRITE(PCH_PP_ON_DELAYS
, dev_priv
->regfile
.savePP_ON_DELAYS
);
256 I915_WRITE(PCH_PP_OFF_DELAYS
, dev_priv
->regfile
.savePP_OFF_DELAYS
);
257 I915_WRITE(PCH_PP_DIVISOR
, dev_priv
->regfile
.savePP_DIVISOR
);
258 I915_WRITE(PCH_PP_CONTROL
, dev_priv
->regfile
.savePP_CONTROL
);
259 } else if (!IS_VALLEYVIEW(dev
)) {
260 I915_WRITE(PP_ON_DELAYS
, dev_priv
->regfile
.savePP_ON_DELAYS
);
261 I915_WRITE(PP_OFF_DELAYS
, dev_priv
->regfile
.savePP_OFF_DELAYS
);
262 I915_WRITE(PP_DIVISOR
, dev_priv
->regfile
.savePP_DIVISOR
);
263 I915_WRITE(PP_CONTROL
, dev_priv
->regfile
.savePP_CONTROL
);
266 /* only restore FBC info on the platform that supports FBC*/
267 intel_fbc_disable(dev
);
269 /* restore FBC interval */
270 if (HAS_FBC(dev
) && INTEL_INFO(dev
)->gen
<= 4 && !IS_G4X(dev
))
271 I915_WRITE(FBC_CONTROL
, dev_priv
->regfile
.saveFBC_CONTROL
);
273 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
274 i915_restore_vga(dev
);
276 i915_redisable_vga(dev
);
279 int i915_save_state(struct drm_device
*dev
)
281 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
284 mutex_lock(&dev
->struct_mutex
);
286 i915_save_display(dev
);
288 if (!drm_core_check_feature(dev
, DRIVER_MODESET
)) {
289 /* Interrupt state */
290 if (HAS_PCH_SPLIT(dev
)) {
291 dev_priv
->regfile
.saveDEIER
= I915_READ(DEIER
);
292 dev_priv
->regfile
.saveDEIMR
= I915_READ(DEIMR
);
293 dev_priv
->regfile
.saveGTIER
= I915_READ(GTIER
);
294 dev_priv
->regfile
.saveGTIMR
= I915_READ(GTIMR
);
295 dev_priv
->regfile
.saveFDI_RXA_IMR
= I915_READ(_FDI_RXA_IMR
);
296 dev_priv
->regfile
.saveFDI_RXB_IMR
= I915_READ(_FDI_RXB_IMR
);
297 dev_priv
->regfile
.saveMCHBAR_RENDER_STANDBY
=
298 I915_READ(RSTDBYCTL
);
299 dev_priv
->regfile
.savePCH_PORT_HOTPLUG
= I915_READ(PCH_PORT_HOTPLUG
);
301 dev_priv
->regfile
.saveIER
= I915_READ(IER
);
302 dev_priv
->regfile
.saveIMR
= I915_READ(IMR
);
307 pci_read_config_word(dev
->pdev
, GCDGMBUS
,
308 &dev_priv
->regfile
.saveGCDGMBUS
);
310 /* Cache mode state */
311 if (INTEL_INFO(dev
)->gen
< 7)
312 dev_priv
->regfile
.saveCACHE_MODE_0
= I915_READ(CACHE_MODE_0
);
314 /* Memory Arbitration state */
315 dev_priv
->regfile
.saveMI_ARB_STATE
= I915_READ(MI_ARB_STATE
);
318 for (i
= 0; i
< 16; i
++) {
319 dev_priv
->regfile
.saveSWF0
[i
] = I915_READ(SWF00
+ (i
<< 2));
320 dev_priv
->regfile
.saveSWF1
[i
] = I915_READ(SWF10
+ (i
<< 2));
322 for (i
= 0; i
< 3; i
++)
323 dev_priv
->regfile
.saveSWF2
[i
] = I915_READ(SWF30
+ (i
<< 2));
325 mutex_unlock(&dev
->struct_mutex
);
330 int i915_restore_state(struct drm_device
*dev
)
332 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
335 mutex_lock(&dev
->struct_mutex
);
337 i915_gem_restore_fences(dev
);
340 pci_write_config_word(dev
->pdev
, GCDGMBUS
,
341 dev_priv
->regfile
.saveGCDGMBUS
);
342 i915_restore_display(dev
);
344 if (!drm_core_check_feature(dev
, DRIVER_MODESET
)) {
345 /* Interrupt state */
346 if (HAS_PCH_SPLIT(dev
)) {
347 I915_WRITE(DEIER
, dev_priv
->regfile
.saveDEIER
);
348 I915_WRITE(DEIMR
, dev_priv
->regfile
.saveDEIMR
);
349 I915_WRITE(GTIER
, dev_priv
->regfile
.saveGTIER
);
350 I915_WRITE(GTIMR
, dev_priv
->regfile
.saveGTIMR
);
351 I915_WRITE(_FDI_RXA_IMR
, dev_priv
->regfile
.saveFDI_RXA_IMR
);
352 I915_WRITE(_FDI_RXB_IMR
, dev_priv
->regfile
.saveFDI_RXB_IMR
);
353 I915_WRITE(PCH_PORT_HOTPLUG
, dev_priv
->regfile
.savePCH_PORT_HOTPLUG
);
354 I915_WRITE(RSTDBYCTL
,
355 dev_priv
->regfile
.saveMCHBAR_RENDER_STANDBY
);
357 I915_WRITE(IER
, dev_priv
->regfile
.saveIER
);
358 I915_WRITE(IMR
, dev_priv
->regfile
.saveIMR
);
362 /* Cache mode state */
363 if (INTEL_INFO(dev
)->gen
< 7)
364 I915_WRITE(CACHE_MODE_0
, dev_priv
->regfile
.saveCACHE_MODE_0
|
367 /* Memory arbitration state */
368 I915_WRITE(MI_ARB_STATE
, dev_priv
->regfile
.saveMI_ARB_STATE
| 0xffff0000);
370 for (i
= 0; i
< 16; i
++) {
371 I915_WRITE(SWF00
+ (i
<< 2), dev_priv
->regfile
.saveSWF0
[i
]);
372 I915_WRITE(SWF10
+ (i
<< 2), dev_priv
->regfile
.saveSWF1
[i
]);
374 for (i
= 0; i
< 3; i
++)
375 I915_WRITE(SWF30
+ (i
<< 2), dev_priv
->regfile
.saveSWF2
[i
]);
377 mutex_unlock(&dev
->struct_mutex
);
379 intel_i2c_reset(dev
);