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_SPLIT(dev
)) {
207 dev_priv
->regfile
.savePP_CONTROL
= I915_READ(PCH_PP_CONTROL
);
208 if (HAS_PCH_IBX(dev
) || HAS_PCH_CPT(dev
))
209 dev_priv
->regfile
.saveLVDS
= I915_READ(PCH_LVDS
);
210 } else if (IS_VALLEYVIEW(dev
)) {
211 dev_priv
->regfile
.savePP_CONTROL
= I915_READ(PP_CONTROL
);
212 dev_priv
->regfile
.savePFIT_PGM_RATIOS
= I915_READ(PFIT_PGM_RATIOS
);
214 dev_priv
->regfile
.saveBLC_HIST_CTL
=
215 I915_READ(VLV_BLC_HIST_CTL(PIPE_A
));
216 dev_priv
->regfile
.saveBLC_HIST_CTL_B
=
217 I915_READ(VLV_BLC_HIST_CTL(PIPE_B
));
219 dev_priv
->regfile
.savePP_CONTROL
= I915_READ(PP_CONTROL
);
220 dev_priv
->regfile
.savePFIT_PGM_RATIOS
= I915_READ(PFIT_PGM_RATIOS
);
221 dev_priv
->regfile
.saveBLC_HIST_CTL
= I915_READ(BLC_HIST_CTL
);
222 if (IS_MOBILE(dev
) && !IS_I830(dev
))
223 dev_priv
->regfile
.saveLVDS
= I915_READ(LVDS
);
226 if (!IS_I830(dev
) && !IS_845G(dev
) && !HAS_PCH_SPLIT(dev
))
227 dev_priv
->regfile
.savePFIT_CONTROL
= I915_READ(PFIT_CONTROL
);
229 if (HAS_PCH_SPLIT(dev
)) {
230 dev_priv
->regfile
.savePP_ON_DELAYS
= I915_READ(PCH_PP_ON_DELAYS
);
231 dev_priv
->regfile
.savePP_OFF_DELAYS
= I915_READ(PCH_PP_OFF_DELAYS
);
232 dev_priv
->regfile
.savePP_DIVISOR
= I915_READ(PCH_PP_DIVISOR
);
234 dev_priv
->regfile
.savePP_ON_DELAYS
= I915_READ(PP_ON_DELAYS
);
235 dev_priv
->regfile
.savePP_OFF_DELAYS
= I915_READ(PP_OFF_DELAYS
);
236 dev_priv
->regfile
.savePP_DIVISOR
= I915_READ(PP_DIVISOR
);
239 /* Only regfile.save FBC state on the platform that supports FBC */
241 if (HAS_PCH_SPLIT(dev
)) {
242 dev_priv
->regfile
.saveDPFC_CB_BASE
= I915_READ(ILK_DPFC_CB_BASE
);
243 } else if (IS_GM45(dev
)) {
244 dev_priv
->regfile
.saveDPFC_CB_BASE
= I915_READ(DPFC_CB_BASE
);
246 dev_priv
->regfile
.saveFBC_CFB_BASE
= I915_READ(FBC_CFB_BASE
);
247 dev_priv
->regfile
.saveFBC_LL_BASE
= I915_READ(FBC_LL_BASE
);
248 dev_priv
->regfile
.saveFBC_CONTROL2
= I915_READ(FBC_CONTROL2
);
249 dev_priv
->regfile
.saveFBC_CONTROL
= I915_READ(FBC_CONTROL
);
253 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
257 static void i915_restore_display(struct drm_device
*dev
)
259 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
260 u32 mask
= 0xffffffff;
262 /* Display arbitration */
263 if (INTEL_INFO(dev
)->gen
<= 4)
264 I915_WRITE(DSPARB
, dev_priv
->regfile
.saveDSPARB
);
266 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
267 i915_restore_display_reg(dev
);
269 if (drm_core_check_feature(dev
, DRIVER_MODESET
))
270 mask
= ~LVDS_PORT_EN
;
272 if (HAS_PCH_IBX(dev
) || HAS_PCH_CPT(dev
))
273 I915_WRITE(PCH_LVDS
, dev_priv
->regfile
.saveLVDS
& mask
);
274 else if (INTEL_INFO(dev
)->gen
<= 4 && IS_MOBILE(dev
) && !IS_I830(dev
))
275 I915_WRITE(LVDS
, dev_priv
->regfile
.saveLVDS
& mask
);
277 if (!IS_I830(dev
) && !IS_845G(dev
) && !HAS_PCH_SPLIT(dev
))
278 I915_WRITE(PFIT_CONTROL
, dev_priv
->regfile
.savePFIT_CONTROL
);
280 if (HAS_PCH_SPLIT(dev
)) {
281 I915_WRITE(PCH_PP_ON_DELAYS
, dev_priv
->regfile
.savePP_ON_DELAYS
);
282 I915_WRITE(PCH_PP_OFF_DELAYS
, dev_priv
->regfile
.savePP_OFF_DELAYS
);
283 I915_WRITE(PCH_PP_DIVISOR
, dev_priv
->regfile
.savePP_DIVISOR
);
284 I915_WRITE(PCH_PP_CONTROL
, dev_priv
->regfile
.savePP_CONTROL
);
285 I915_WRITE(RSTDBYCTL
,
286 dev_priv
->regfile
.saveMCHBAR_RENDER_STANDBY
);
287 } else if (IS_VALLEYVIEW(dev
)) {
288 I915_WRITE(VLV_BLC_HIST_CTL(PIPE_A
),
289 dev_priv
->regfile
.saveBLC_HIST_CTL
);
290 I915_WRITE(VLV_BLC_HIST_CTL(PIPE_B
),
291 dev_priv
->regfile
.saveBLC_HIST_CTL
);
293 I915_WRITE(PFIT_PGM_RATIOS
, dev_priv
->regfile
.savePFIT_PGM_RATIOS
);
294 I915_WRITE(BLC_HIST_CTL
, dev_priv
->regfile
.saveBLC_HIST_CTL
);
295 I915_WRITE(PP_ON_DELAYS
, dev_priv
->regfile
.savePP_ON_DELAYS
);
296 I915_WRITE(PP_OFF_DELAYS
, dev_priv
->regfile
.savePP_OFF_DELAYS
);
297 I915_WRITE(PP_DIVISOR
, dev_priv
->regfile
.savePP_DIVISOR
);
298 I915_WRITE(PP_CONTROL
, dev_priv
->regfile
.savePP_CONTROL
);
301 /* only restore FBC info on the platform that supports FBC*/
302 intel_disable_fbc(dev
);
304 if (HAS_PCH_SPLIT(dev
)) {
305 I915_WRITE(ILK_DPFC_CB_BASE
, dev_priv
->regfile
.saveDPFC_CB_BASE
);
306 } else if (IS_GM45(dev
)) {
307 I915_WRITE(DPFC_CB_BASE
, dev_priv
->regfile
.saveDPFC_CB_BASE
);
309 I915_WRITE(FBC_CFB_BASE
, dev_priv
->regfile
.saveFBC_CFB_BASE
);
310 I915_WRITE(FBC_LL_BASE
, dev_priv
->regfile
.saveFBC_LL_BASE
);
311 I915_WRITE(FBC_CONTROL2
, dev_priv
->regfile
.saveFBC_CONTROL2
);
312 I915_WRITE(FBC_CONTROL
, dev_priv
->regfile
.saveFBC_CONTROL
);
316 if (!drm_core_check_feature(dev
, DRIVER_MODESET
))
317 i915_restore_vga(dev
);
319 i915_redisable_vga(dev
);
322 int i915_save_state(struct drm_device
*dev
)
324 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
327 if (INTEL_INFO(dev
)->gen
<= 4)
328 pci_read_config_byte(dev
->pdev
, LBB
,
329 &dev_priv
->regfile
.saveLBB
);
331 mutex_lock(&dev
->struct_mutex
);
333 i915_save_display(dev
);
335 if (!drm_core_check_feature(dev
, DRIVER_MODESET
)) {
336 /* Interrupt state */
337 if (HAS_PCH_SPLIT(dev
)) {
338 dev_priv
->regfile
.saveDEIER
= I915_READ(DEIER
);
339 dev_priv
->regfile
.saveDEIMR
= I915_READ(DEIMR
);
340 dev_priv
->regfile
.saveGTIER
= I915_READ(GTIER
);
341 dev_priv
->regfile
.saveGTIMR
= I915_READ(GTIMR
);
342 dev_priv
->regfile
.saveFDI_RXA_IMR
= I915_READ(_FDI_RXA_IMR
);
343 dev_priv
->regfile
.saveFDI_RXB_IMR
= I915_READ(_FDI_RXB_IMR
);
344 dev_priv
->regfile
.saveMCHBAR_RENDER_STANDBY
=
345 I915_READ(RSTDBYCTL
);
346 dev_priv
->regfile
.savePCH_PORT_HOTPLUG
= I915_READ(PCH_PORT_HOTPLUG
);
348 dev_priv
->regfile
.saveIER
= I915_READ(IER
);
349 dev_priv
->regfile
.saveIMR
= I915_READ(IMR
);
353 intel_disable_gt_powersave(dev
);
355 /* Cache mode state */
356 if (INTEL_INFO(dev
)->gen
< 7)
357 dev_priv
->regfile
.saveCACHE_MODE_0
= I915_READ(CACHE_MODE_0
);
359 /* Memory Arbitration state */
360 dev_priv
->regfile
.saveMI_ARB_STATE
= I915_READ(MI_ARB_STATE
);
363 for (i
= 0; i
< 16; i
++) {
364 dev_priv
->regfile
.saveSWF0
[i
] = I915_READ(SWF00
+ (i
<< 2));
365 dev_priv
->regfile
.saveSWF1
[i
] = I915_READ(SWF10
+ (i
<< 2));
367 for (i
= 0; i
< 3; i
++)
368 dev_priv
->regfile
.saveSWF2
[i
] = I915_READ(SWF30
+ (i
<< 2));
370 mutex_unlock(&dev
->struct_mutex
);
375 int i915_restore_state(struct drm_device
*dev
)
377 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
380 if (INTEL_INFO(dev
)->gen
<= 4)
381 pci_write_config_byte(dev
->pdev
, LBB
,
382 dev_priv
->regfile
.saveLBB
);
384 mutex_lock(&dev
->struct_mutex
);
386 i915_gem_restore_fences(dev
);
387 i915_restore_display(dev
);
389 if (!drm_core_check_feature(dev
, DRIVER_MODESET
)) {
390 /* Interrupt state */
391 if (HAS_PCH_SPLIT(dev
)) {
392 I915_WRITE(DEIER
, dev_priv
->regfile
.saveDEIER
);
393 I915_WRITE(DEIMR
, dev_priv
->regfile
.saveDEIMR
);
394 I915_WRITE(GTIER
, dev_priv
->regfile
.saveGTIER
);
395 I915_WRITE(GTIMR
, dev_priv
->regfile
.saveGTIMR
);
396 I915_WRITE(_FDI_RXA_IMR
, dev_priv
->regfile
.saveFDI_RXA_IMR
);
397 I915_WRITE(_FDI_RXB_IMR
, dev_priv
->regfile
.saveFDI_RXB_IMR
);
398 I915_WRITE(PCH_PORT_HOTPLUG
, dev_priv
->regfile
.savePCH_PORT_HOTPLUG
);
400 I915_WRITE(IER
, dev_priv
->regfile
.saveIER
);
401 I915_WRITE(IMR
, dev_priv
->regfile
.saveIMR
);
405 /* Cache mode state */
406 if (INTEL_INFO(dev
)->gen
< 7)
407 I915_WRITE(CACHE_MODE_0
, dev_priv
->regfile
.saveCACHE_MODE_0
|
410 /* Memory arbitration state */
411 I915_WRITE(MI_ARB_STATE
, dev_priv
->regfile
.saveMI_ARB_STATE
| 0xffff0000);
413 for (i
= 0; i
< 16; i
++) {
414 I915_WRITE(SWF00
+ (i
<< 2), dev_priv
->regfile
.saveSWF0
[i
]);
415 I915_WRITE(SWF10
+ (i
<< 2), dev_priv
->regfile
.saveSWF1
[i
]);
417 for (i
= 0; i
< 3; i
++)
418 I915_WRITE(SWF30
+ (i
<< 2), dev_priv
->regfile
.saveSWF2
[i
]);
420 mutex_unlock(&dev
->struct_mutex
);
422 intel_i2c_reset(dev
);