3 * Copyright 2008 (c) Intel Corporation
4 * Jesse Barnes <jbarnes@virtuousgeek.org>
5 * Copyright 2013 (c) Intel Corporation
6 * Daniel Vetter <daniel.vetter@ffwll.ch>
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include <drm/i915_drm.h>
31 #include "intel_drv.h"
34 static bool i915_pipe_enabled(struct drm_device
*dev
, enum pipe pipe
)
36 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
39 /* On IVB, 3rd pipe shares PLL with another one */
43 if (HAS_PCH_SPLIT(dev
))
44 dpll_reg
= PCH_DPLL(pipe
);
46 dpll_reg
= (pipe
== PIPE_A
) ? _DPLL_A
: _DPLL_B
;
48 return (I915_READ(dpll_reg
) & DPLL_VCO_ENABLE
);
51 static void i915_save_palette(struct drm_device
*dev
, enum pipe pipe
)
53 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
54 unsigned long reg
= (pipe
== PIPE_A
? _PALETTE_A
: _PALETTE_B
);
58 if (!i915_pipe_enabled(dev
, pipe
))
61 if (HAS_PCH_SPLIT(dev
))
62 reg
= (pipe
== PIPE_A
) ? _LGC_PALETTE_A
: _LGC_PALETTE_B
;
65 array
= dev_priv
->regfile
.save_palette_a
;
67 array
= dev_priv
->regfile
.save_palette_b
;
69 for (i
= 0; i
< 256; i
++)
70 array
[i
] = I915_READ(reg
+ (i
<< 2));
73 static void i915_restore_palette(struct drm_device
*dev
, enum pipe pipe
)
75 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
76 unsigned long reg
= (pipe
== PIPE_A
? _PALETTE_A
: _PALETTE_B
);
80 if (!i915_pipe_enabled(dev
, pipe
))
83 if (HAS_PCH_SPLIT(dev
))
84 reg
= (pipe
== PIPE_A
) ? _LGC_PALETTE_A
: _LGC_PALETTE_B
;
87 array
= dev_priv
->regfile
.save_palette_a
;
89 array
= dev_priv
->regfile
.save_palette_b
;
91 for (i
= 0; i
< 256; i
++)
92 I915_WRITE(reg
+ (i
<< 2), array
[i
]);
95 void i915_save_display_reg(struct drm_device
*dev
)
97 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
101 dev_priv
->regfile
.saveCURACNTR
= I915_READ(_CURACNTR
);
102 dev_priv
->regfile
.saveCURAPOS
= I915_READ(_CURAPOS
);
103 dev_priv
->regfile
.saveCURABASE
= I915_READ(_CURABASE
);
104 dev_priv
->regfile
.saveCURBCNTR
= I915_READ(_CURBCNTR
);
105 dev_priv
->regfile
.saveCURBPOS
= I915_READ(_CURBPOS
);
106 dev_priv
->regfile
.saveCURBBASE
= I915_READ(_CURBBASE
);
108 dev_priv
->regfile
.saveCURSIZE
= I915_READ(CURSIZE
);
110 if (HAS_PCH_SPLIT(dev
)) {
111 dev_priv
->regfile
.savePCH_DREF_CONTROL
= I915_READ(PCH_DREF_CONTROL
);
112 dev_priv
->regfile
.saveDISP_ARB_CTL
= I915_READ(DISP_ARB_CTL
);
115 /* Pipe & plane A info */
116 dev_priv
->regfile
.savePIPEACONF
= I915_READ(_PIPEACONF
);
117 dev_priv
->regfile
.savePIPEASRC
= I915_READ(_PIPEASRC
);
118 if (HAS_PCH_SPLIT(dev
)) {
119 dev_priv
->regfile
.saveFPA0
= I915_READ(_PCH_FPA0
);
120 dev_priv
->regfile
.saveFPA1
= I915_READ(_PCH_FPA1
);
121 dev_priv
->regfile
.saveDPLL_A
= I915_READ(_PCH_DPLL_A
);
123 dev_priv
->regfile
.saveFPA0
= I915_READ(_FPA0
);
124 dev_priv
->regfile
.saveFPA1
= I915_READ(_FPA1
);
125 dev_priv
->regfile
.saveDPLL_A
= I915_READ(_DPLL_A
);
127 if (INTEL_INFO(dev
)->gen
>= 4 && !HAS_PCH_SPLIT(dev
))
128 dev_priv
->regfile
.saveDPLL_A_MD
= I915_READ(_DPLL_A_MD
);
129 dev_priv
->regfile
.saveHTOTAL_A
= I915_READ(_HTOTAL_A
);
130 dev_priv
->regfile
.saveHBLANK_A
= I915_READ(_HBLANK_A
);
131 dev_priv
->regfile
.saveHSYNC_A
= I915_READ(_HSYNC_A
);
132 dev_priv
->regfile
.saveVTOTAL_A
= I915_READ(_VTOTAL_A
);
133 dev_priv
->regfile
.saveVBLANK_A
= I915_READ(_VBLANK_A
);
134 dev_priv
->regfile
.saveVSYNC_A
= I915_READ(_VSYNC_A
);
135 if (!HAS_PCH_SPLIT(dev
))
136 dev_priv
->regfile
.saveBCLRPAT_A
= I915_READ(_BCLRPAT_A
);
138 if (HAS_PCH_SPLIT(dev
)) {
139 dev_priv
->regfile
.savePIPEA_DATA_M1
= I915_READ(_PIPEA_DATA_M1
);
140 dev_priv
->regfile
.savePIPEA_DATA_N1
= I915_READ(_PIPEA_DATA_N1
);
141 dev_priv
->regfile
.savePIPEA_LINK_M1
= I915_READ(_PIPEA_LINK_M1
);
142 dev_priv
->regfile
.savePIPEA_LINK_N1
= I915_READ(_PIPEA_LINK_N1
);
144 dev_priv
->regfile
.saveFDI_TXA_CTL
= I915_READ(_FDI_TXA_CTL
);
145 dev_priv
->regfile
.saveFDI_RXA_CTL
= I915_READ(_FDI_RXA_CTL
);
147 dev_priv
->regfile
.savePFA_CTL_1
= I915_READ(_PFA_CTL_1
);
148 dev_priv
->regfile
.savePFA_WIN_SZ
= I915_READ(_PFA_WIN_SZ
);
149 dev_priv
->regfile
.savePFA_WIN_POS
= I915_READ(_PFA_WIN_POS
);
151 dev_priv
->regfile
.saveTRANSACONF
= I915_READ(_PCH_TRANSACONF
);
152 dev_priv
->regfile
.saveTRANS_HTOTAL_A
= I915_READ(_PCH_TRANS_HTOTAL_A
);
153 dev_priv
->regfile
.saveTRANS_HBLANK_A
= I915_READ(_PCH_TRANS_HBLANK_A
);
154 dev_priv
->regfile
.saveTRANS_HSYNC_A
= I915_READ(_PCH_TRANS_HSYNC_A
);
155 dev_priv
->regfile
.saveTRANS_VTOTAL_A
= I915_READ(_PCH_TRANS_VTOTAL_A
);
156 dev_priv
->regfile
.saveTRANS_VBLANK_A
= I915_READ(_PCH_TRANS_VBLANK_A
);
157 dev_priv
->regfile
.saveTRANS_VSYNC_A
= I915_READ(_PCH_TRANS_VSYNC_A
);
160 dev_priv
->regfile
.saveDSPACNTR
= I915_READ(_DSPACNTR
);
161 dev_priv
->regfile
.saveDSPASTRIDE
= I915_READ(_DSPASTRIDE
);
162 dev_priv
->regfile
.saveDSPASIZE
= I915_READ(_DSPASIZE
);
163 dev_priv
->regfile
.saveDSPAPOS
= I915_READ(_DSPAPOS
);
164 dev_priv
->regfile
.saveDSPAADDR
= I915_READ(_DSPAADDR
);
165 if (INTEL_INFO(dev
)->gen
>= 4) {
166 dev_priv
->regfile
.saveDSPASURF
= I915_READ(_DSPASURF
);
167 dev_priv
->regfile
.saveDSPATILEOFF
= I915_READ(_DSPATILEOFF
);
169 i915_save_palette(dev
, PIPE_A
);
170 dev_priv
->regfile
.savePIPEASTAT
= I915_READ(_PIPEASTAT
);
172 /* Pipe & plane B info */
173 dev_priv
->regfile
.savePIPEBCONF
= I915_READ(_PIPEBCONF
);
174 dev_priv
->regfile
.savePIPEBSRC
= I915_READ(_PIPEBSRC
);
175 if (HAS_PCH_SPLIT(dev
)) {
176 dev_priv
->regfile
.saveFPB0
= I915_READ(_PCH_FPB0
);
177 dev_priv
->regfile
.saveFPB1
= I915_READ(_PCH_FPB1
);
178 dev_priv
->regfile
.saveDPLL_B
= I915_READ(_PCH_DPLL_B
);
180 dev_priv
->regfile
.saveFPB0
= I915_READ(_FPB0
);
181 dev_priv
->regfile
.saveFPB1
= I915_READ(_FPB1
);
182 dev_priv
->regfile
.saveDPLL_B
= I915_READ(_DPLL_B
);
184 if (INTEL_INFO(dev
)->gen
>= 4 && !HAS_PCH_SPLIT(dev
))
185 dev_priv
->regfile
.saveDPLL_B_MD
= I915_READ(_DPLL_B_MD
);
186 dev_priv
->regfile
.saveHTOTAL_B
= I915_READ(_HTOTAL_B
);
187 dev_priv
->regfile
.saveHBLANK_B
= I915_READ(_HBLANK_B
);
188 dev_priv
->regfile
.saveHSYNC_B
= I915_READ(_HSYNC_B
);
189 dev_priv
->regfile
.saveVTOTAL_B
= I915_READ(_VTOTAL_B
);
190 dev_priv
->regfile
.saveVBLANK_B
= I915_READ(_VBLANK_B
);
191 dev_priv
->regfile
.saveVSYNC_B
= I915_READ(_VSYNC_B
);
192 if (!HAS_PCH_SPLIT(dev
))
193 dev_priv
->regfile
.saveBCLRPAT_B
= I915_READ(_BCLRPAT_B
);
195 if (HAS_PCH_SPLIT(dev
)) {
196 dev_priv
->regfile
.savePIPEB_DATA_M1
= I915_READ(_PIPEB_DATA_M1
);
197 dev_priv
->regfile
.savePIPEB_DATA_N1
= I915_READ(_PIPEB_DATA_N1
);
198 dev_priv
->regfile
.savePIPEB_LINK_M1
= I915_READ(_PIPEB_LINK_M1
);
199 dev_priv
->regfile
.savePIPEB_LINK_N1
= I915_READ(_PIPEB_LINK_N1
);
201 dev_priv
->regfile
.saveFDI_TXB_CTL
= I915_READ(_FDI_TXB_CTL
);
202 dev_priv
->regfile
.saveFDI_RXB_CTL
= I915_READ(_FDI_RXB_CTL
);
204 dev_priv
->regfile
.savePFB_CTL_1
= I915_READ(_PFB_CTL_1
);
205 dev_priv
->regfile
.savePFB_WIN_SZ
= I915_READ(_PFB_WIN_SZ
);
206 dev_priv
->regfile
.savePFB_WIN_POS
= I915_READ(_PFB_WIN_POS
);
208 dev_priv
->regfile
.saveTRANSBCONF
= I915_READ(_PCH_TRANSBCONF
);
209 dev_priv
->regfile
.saveTRANS_HTOTAL_B
= I915_READ(_PCH_TRANS_HTOTAL_B
);
210 dev_priv
->regfile
.saveTRANS_HBLANK_B
= I915_READ(_PCH_TRANS_HBLANK_B
);
211 dev_priv
->regfile
.saveTRANS_HSYNC_B
= I915_READ(_PCH_TRANS_HSYNC_B
);
212 dev_priv
->regfile
.saveTRANS_VTOTAL_B
= I915_READ(_PCH_TRANS_VTOTAL_B
);
213 dev_priv
->regfile
.saveTRANS_VBLANK_B
= I915_READ(_PCH_TRANS_VBLANK_B
);
214 dev_priv
->regfile
.saveTRANS_VSYNC_B
= I915_READ(_PCH_TRANS_VSYNC_B
);
217 dev_priv
->regfile
.saveDSPBCNTR
= I915_READ(_DSPBCNTR
);
218 dev_priv
->regfile
.saveDSPBSTRIDE
= I915_READ(_DSPBSTRIDE
);
219 dev_priv
->regfile
.saveDSPBSIZE
= I915_READ(_DSPBSIZE
);
220 dev_priv
->regfile
.saveDSPBPOS
= I915_READ(_DSPBPOS
);
221 dev_priv
->regfile
.saveDSPBADDR
= I915_READ(_DSPBADDR
);
222 if (INTEL_INFO(dev
)->gen
>= 4) {
223 dev_priv
->regfile
.saveDSPBSURF
= I915_READ(_DSPBSURF
);
224 dev_priv
->regfile
.saveDSPBTILEOFF
= I915_READ(_DSPBTILEOFF
);
226 i915_save_palette(dev
, PIPE_B
);
227 dev_priv
->regfile
.savePIPEBSTAT
= I915_READ(_PIPEBSTAT
);
230 switch (INTEL_INFO(dev
)->gen
) {
233 for (i
= 0; i
< 16; i
++)
234 dev_priv
->regfile
.saveFENCE
[i
] = I915_READ64(FENCE_REG_SANDYBRIDGE_0
+ (i
* 8));
238 for (i
= 0; i
< 16; i
++)
239 dev_priv
->regfile
.saveFENCE
[i
] = I915_READ64(FENCE_REG_965_0
+ (i
* 8));
242 if (IS_I945G(dev
) || IS_I945GM(dev
) || IS_G33(dev
))
243 for (i
= 0; i
< 8; i
++)
244 dev_priv
->regfile
.saveFENCE
[i
+8] = I915_READ(FENCE_REG_945_8
+ (i
* 4));
246 for (i
= 0; i
< 8; i
++)
247 dev_priv
->regfile
.saveFENCE
[i
] = I915_READ(FENCE_REG_830_0
+ (i
* 4));
252 if (HAS_PCH_SPLIT(dev
))
253 dev_priv
->regfile
.saveADPA
= I915_READ(PCH_ADPA
);
255 dev_priv
->regfile
.saveADPA
= I915_READ(ADPA
);
257 /* Display Port state */
258 if (SUPPORTS_INTEGRATED_DP(dev
)) {
259 dev_priv
->regfile
.saveDP_B
= I915_READ(DP_B
);
260 dev_priv
->regfile
.saveDP_C
= I915_READ(DP_C
);
261 dev_priv
->regfile
.saveDP_D
= I915_READ(DP_D
);
262 dev_priv
->regfile
.savePIPEA_GMCH_DATA_M
= I915_READ(_PIPEA_DATA_M_G4X
);
263 dev_priv
->regfile
.savePIPEB_GMCH_DATA_M
= I915_READ(_PIPEB_DATA_M_G4X
);
264 dev_priv
->regfile
.savePIPEA_GMCH_DATA_N
= I915_READ(_PIPEA_DATA_N_G4X
);
265 dev_priv
->regfile
.savePIPEB_GMCH_DATA_N
= I915_READ(_PIPEB_DATA_N_G4X
);
266 dev_priv
->regfile
.savePIPEA_DP_LINK_M
= I915_READ(_PIPEA_LINK_M_G4X
);
267 dev_priv
->regfile
.savePIPEB_DP_LINK_M
= I915_READ(_PIPEB_LINK_M_G4X
);
268 dev_priv
->regfile
.savePIPEA_DP_LINK_N
= I915_READ(_PIPEA_LINK_N_G4X
);
269 dev_priv
->regfile
.savePIPEB_DP_LINK_N
= I915_READ(_PIPEB_LINK_N_G4X
);
271 /* FIXME: regfile.save TV & SDVO state */
276 void i915_restore_display_reg(struct drm_device
*dev
)
278 struct drm_i915_private
*dev_priv
= dev
->dev_private
;
279 int dpll_a_reg
, fpa0_reg
, fpa1_reg
;
280 int dpll_b_reg
, fpb0_reg
, fpb1_reg
;
283 /* Display port ratios (must be done before clock is set) */
284 if (SUPPORTS_INTEGRATED_DP(dev
)) {
285 I915_WRITE(_PIPEA_DATA_M_G4X
, dev_priv
->regfile
.savePIPEA_GMCH_DATA_M
);
286 I915_WRITE(_PIPEB_DATA_M_G4X
, dev_priv
->regfile
.savePIPEB_GMCH_DATA_M
);
287 I915_WRITE(_PIPEA_DATA_N_G4X
, dev_priv
->regfile
.savePIPEA_GMCH_DATA_N
);
288 I915_WRITE(_PIPEB_DATA_N_G4X
, dev_priv
->regfile
.savePIPEB_GMCH_DATA_N
);
289 I915_WRITE(_PIPEA_LINK_M_G4X
, dev_priv
->regfile
.savePIPEA_DP_LINK_M
);
290 I915_WRITE(_PIPEB_LINK_M_G4X
, dev_priv
->regfile
.savePIPEB_DP_LINK_M
);
291 I915_WRITE(_PIPEA_LINK_N_G4X
, dev_priv
->regfile
.savePIPEA_DP_LINK_N
);
292 I915_WRITE(_PIPEB_LINK_N_G4X
, dev_priv
->regfile
.savePIPEB_DP_LINK_N
);
296 switch (INTEL_INFO(dev
)->gen
) {
299 for (i
= 0; i
< 16; i
++)
300 I915_WRITE64(FENCE_REG_SANDYBRIDGE_0
+ (i
* 8), dev_priv
->regfile
.saveFENCE
[i
]);
304 for (i
= 0; i
< 16; i
++)
305 I915_WRITE64(FENCE_REG_965_0
+ (i
* 8), dev_priv
->regfile
.saveFENCE
[i
]);
309 if (IS_I945G(dev
) || IS_I945GM(dev
) || IS_G33(dev
))
310 for (i
= 0; i
< 8; i
++)
311 I915_WRITE(FENCE_REG_945_8
+ (i
* 4), dev_priv
->regfile
.saveFENCE
[i
+8]);
312 for (i
= 0; i
< 8; i
++)
313 I915_WRITE(FENCE_REG_830_0
+ (i
* 4), dev_priv
->regfile
.saveFENCE
[i
]);
318 if (HAS_PCH_SPLIT(dev
)) {
319 dpll_a_reg
= _PCH_DPLL_A
;
320 dpll_b_reg
= _PCH_DPLL_B
;
321 fpa0_reg
= _PCH_FPA0
;
322 fpb0_reg
= _PCH_FPB0
;
323 fpa1_reg
= _PCH_FPA1
;
324 fpb1_reg
= _PCH_FPB1
;
326 dpll_a_reg
= _DPLL_A
;
327 dpll_b_reg
= _DPLL_B
;
334 if (HAS_PCH_SPLIT(dev
)) {
335 I915_WRITE(PCH_DREF_CONTROL
, dev_priv
->regfile
.savePCH_DREF_CONTROL
);
336 I915_WRITE(DISP_ARB_CTL
, dev_priv
->regfile
.saveDISP_ARB_CTL
);
339 /* Pipe & plane A info */
340 /* Prime the clock */
341 if (dev_priv
->regfile
.saveDPLL_A
& DPLL_VCO_ENABLE
) {
342 I915_WRITE(dpll_a_reg
, dev_priv
->regfile
.saveDPLL_A
&
344 POSTING_READ(dpll_a_reg
);
347 I915_WRITE(fpa0_reg
, dev_priv
->regfile
.saveFPA0
);
348 I915_WRITE(fpa1_reg
, dev_priv
->regfile
.saveFPA1
);
349 /* Actually enable it */
350 I915_WRITE(dpll_a_reg
, dev_priv
->regfile
.saveDPLL_A
);
351 POSTING_READ(dpll_a_reg
);
353 if (INTEL_INFO(dev
)->gen
>= 4 && !HAS_PCH_SPLIT(dev
)) {
354 I915_WRITE(_DPLL_A_MD
, dev_priv
->regfile
.saveDPLL_A_MD
);
355 POSTING_READ(_DPLL_A_MD
);
360 I915_WRITE(_HTOTAL_A
, dev_priv
->regfile
.saveHTOTAL_A
);
361 I915_WRITE(_HBLANK_A
, dev_priv
->regfile
.saveHBLANK_A
);
362 I915_WRITE(_HSYNC_A
, dev_priv
->regfile
.saveHSYNC_A
);
363 I915_WRITE(_VTOTAL_A
, dev_priv
->regfile
.saveVTOTAL_A
);
364 I915_WRITE(_VBLANK_A
, dev_priv
->regfile
.saveVBLANK_A
);
365 I915_WRITE(_VSYNC_A
, dev_priv
->regfile
.saveVSYNC_A
);
366 if (!HAS_PCH_SPLIT(dev
))
367 I915_WRITE(_BCLRPAT_A
, dev_priv
->regfile
.saveBCLRPAT_A
);
369 if (HAS_PCH_SPLIT(dev
)) {
370 I915_WRITE(_PIPEA_DATA_M1
, dev_priv
->regfile
.savePIPEA_DATA_M1
);
371 I915_WRITE(_PIPEA_DATA_N1
, dev_priv
->regfile
.savePIPEA_DATA_N1
);
372 I915_WRITE(_PIPEA_LINK_M1
, dev_priv
->regfile
.savePIPEA_LINK_M1
);
373 I915_WRITE(_PIPEA_LINK_N1
, dev_priv
->regfile
.savePIPEA_LINK_N1
);
375 I915_WRITE(_FDI_RXA_CTL
, dev_priv
->regfile
.saveFDI_RXA_CTL
);
376 I915_WRITE(_FDI_TXA_CTL
, dev_priv
->regfile
.saveFDI_TXA_CTL
);
378 I915_WRITE(_PFA_CTL_1
, dev_priv
->regfile
.savePFA_CTL_1
);
379 I915_WRITE(_PFA_WIN_SZ
, dev_priv
->regfile
.savePFA_WIN_SZ
);
380 I915_WRITE(_PFA_WIN_POS
, dev_priv
->regfile
.savePFA_WIN_POS
);
382 I915_WRITE(_PCH_TRANSACONF
, dev_priv
->regfile
.saveTRANSACONF
);
383 I915_WRITE(_PCH_TRANS_HTOTAL_A
, dev_priv
->regfile
.saveTRANS_HTOTAL_A
);
384 I915_WRITE(_PCH_TRANS_HBLANK_A
, dev_priv
->regfile
.saveTRANS_HBLANK_A
);
385 I915_WRITE(_PCH_TRANS_HSYNC_A
, dev_priv
->regfile
.saveTRANS_HSYNC_A
);
386 I915_WRITE(_PCH_TRANS_VTOTAL_A
, dev_priv
->regfile
.saveTRANS_VTOTAL_A
);
387 I915_WRITE(_PCH_TRANS_VBLANK_A
, dev_priv
->regfile
.saveTRANS_VBLANK_A
);
388 I915_WRITE(_PCH_TRANS_VSYNC_A
, dev_priv
->regfile
.saveTRANS_VSYNC_A
);
391 /* Restore plane info */
392 I915_WRITE(_DSPASIZE
, dev_priv
->regfile
.saveDSPASIZE
);
393 I915_WRITE(_DSPAPOS
, dev_priv
->regfile
.saveDSPAPOS
);
394 I915_WRITE(_PIPEASRC
, dev_priv
->regfile
.savePIPEASRC
);
395 I915_WRITE(_DSPAADDR
, dev_priv
->regfile
.saveDSPAADDR
);
396 I915_WRITE(_DSPASTRIDE
, dev_priv
->regfile
.saveDSPASTRIDE
);
397 if (INTEL_INFO(dev
)->gen
>= 4) {
398 I915_WRITE(_DSPASURF
, dev_priv
->regfile
.saveDSPASURF
);
399 I915_WRITE(_DSPATILEOFF
, dev_priv
->regfile
.saveDSPATILEOFF
);
402 I915_WRITE(_PIPEACONF
, dev_priv
->regfile
.savePIPEACONF
);
404 i915_restore_palette(dev
, PIPE_A
);
405 /* Enable the plane */
406 I915_WRITE(_DSPACNTR
, dev_priv
->regfile
.saveDSPACNTR
);
407 I915_WRITE(_DSPAADDR
, I915_READ(_DSPAADDR
));
409 /* Pipe & plane B info */
410 if (dev_priv
->regfile
.saveDPLL_B
& DPLL_VCO_ENABLE
) {
411 I915_WRITE(dpll_b_reg
, dev_priv
->regfile
.saveDPLL_B
&
413 POSTING_READ(dpll_b_reg
);
416 I915_WRITE(fpb0_reg
, dev_priv
->regfile
.saveFPB0
);
417 I915_WRITE(fpb1_reg
, dev_priv
->regfile
.saveFPB1
);
418 /* Actually enable it */
419 I915_WRITE(dpll_b_reg
, dev_priv
->regfile
.saveDPLL_B
);
420 POSTING_READ(dpll_b_reg
);
422 if (INTEL_INFO(dev
)->gen
>= 4 && !HAS_PCH_SPLIT(dev
)) {
423 I915_WRITE(_DPLL_B_MD
, dev_priv
->regfile
.saveDPLL_B_MD
);
424 POSTING_READ(_DPLL_B_MD
);
429 I915_WRITE(_HTOTAL_B
, dev_priv
->regfile
.saveHTOTAL_B
);
430 I915_WRITE(_HBLANK_B
, dev_priv
->regfile
.saveHBLANK_B
);
431 I915_WRITE(_HSYNC_B
, dev_priv
->regfile
.saveHSYNC_B
);
432 I915_WRITE(_VTOTAL_B
, dev_priv
->regfile
.saveVTOTAL_B
);
433 I915_WRITE(_VBLANK_B
, dev_priv
->regfile
.saveVBLANK_B
);
434 I915_WRITE(_VSYNC_B
, dev_priv
->regfile
.saveVSYNC_B
);
435 if (!HAS_PCH_SPLIT(dev
))
436 I915_WRITE(_BCLRPAT_B
, dev_priv
->regfile
.saveBCLRPAT_B
);
438 if (HAS_PCH_SPLIT(dev
)) {
439 I915_WRITE(_PIPEB_DATA_M1
, dev_priv
->regfile
.savePIPEB_DATA_M1
);
440 I915_WRITE(_PIPEB_DATA_N1
, dev_priv
->regfile
.savePIPEB_DATA_N1
);
441 I915_WRITE(_PIPEB_LINK_M1
, dev_priv
->regfile
.savePIPEB_LINK_M1
);
442 I915_WRITE(_PIPEB_LINK_N1
, dev_priv
->regfile
.savePIPEB_LINK_N1
);
444 I915_WRITE(_FDI_RXB_CTL
, dev_priv
->regfile
.saveFDI_RXB_CTL
);
445 I915_WRITE(_FDI_TXB_CTL
, dev_priv
->regfile
.saveFDI_TXB_CTL
);
447 I915_WRITE(_PFB_CTL_1
, dev_priv
->regfile
.savePFB_CTL_1
);
448 I915_WRITE(_PFB_WIN_SZ
, dev_priv
->regfile
.savePFB_WIN_SZ
);
449 I915_WRITE(_PFB_WIN_POS
, dev_priv
->regfile
.savePFB_WIN_POS
);
451 I915_WRITE(_PCH_TRANSBCONF
, dev_priv
->regfile
.saveTRANSBCONF
);
452 I915_WRITE(_PCH_TRANS_HTOTAL_B
, dev_priv
->regfile
.saveTRANS_HTOTAL_B
);
453 I915_WRITE(_PCH_TRANS_HBLANK_B
, dev_priv
->regfile
.saveTRANS_HBLANK_B
);
454 I915_WRITE(_PCH_TRANS_HSYNC_B
, dev_priv
->regfile
.saveTRANS_HSYNC_B
);
455 I915_WRITE(_PCH_TRANS_VTOTAL_B
, dev_priv
->regfile
.saveTRANS_VTOTAL_B
);
456 I915_WRITE(_PCH_TRANS_VBLANK_B
, dev_priv
->regfile
.saveTRANS_VBLANK_B
);
457 I915_WRITE(_PCH_TRANS_VSYNC_B
, dev_priv
->regfile
.saveTRANS_VSYNC_B
);
460 /* Restore plane info */
461 I915_WRITE(_DSPBSIZE
, dev_priv
->regfile
.saveDSPBSIZE
);
462 I915_WRITE(_DSPBPOS
, dev_priv
->regfile
.saveDSPBPOS
);
463 I915_WRITE(_PIPEBSRC
, dev_priv
->regfile
.savePIPEBSRC
);
464 I915_WRITE(_DSPBADDR
, dev_priv
->regfile
.saveDSPBADDR
);
465 I915_WRITE(_DSPBSTRIDE
, dev_priv
->regfile
.saveDSPBSTRIDE
);
466 if (INTEL_INFO(dev
)->gen
>= 4) {
467 I915_WRITE(_DSPBSURF
, dev_priv
->regfile
.saveDSPBSURF
);
468 I915_WRITE(_DSPBTILEOFF
, dev_priv
->regfile
.saveDSPBTILEOFF
);
471 I915_WRITE(_PIPEBCONF
, dev_priv
->regfile
.savePIPEBCONF
);
473 i915_restore_palette(dev
, PIPE_B
);
474 /* Enable the plane */
475 I915_WRITE(_DSPBCNTR
, dev_priv
->regfile
.saveDSPBCNTR
);
476 I915_WRITE(_DSPBADDR
, I915_READ(_DSPBADDR
));
479 I915_WRITE(_CURAPOS
, dev_priv
->regfile
.saveCURAPOS
);
480 I915_WRITE(_CURACNTR
, dev_priv
->regfile
.saveCURACNTR
);
481 I915_WRITE(_CURABASE
, dev_priv
->regfile
.saveCURABASE
);
482 I915_WRITE(_CURBPOS
, dev_priv
->regfile
.saveCURBPOS
);
483 I915_WRITE(_CURBCNTR
, dev_priv
->regfile
.saveCURBCNTR
);
484 I915_WRITE(_CURBBASE
, dev_priv
->regfile
.saveCURBBASE
);
486 I915_WRITE(CURSIZE
, dev_priv
->regfile
.saveCURSIZE
);
489 if (HAS_PCH_SPLIT(dev
))
490 I915_WRITE(PCH_ADPA
, dev_priv
->regfile
.saveADPA
);
492 I915_WRITE(ADPA
, dev_priv
->regfile
.saveADPA
);
494 /* Display Port state */
495 if (SUPPORTS_INTEGRATED_DP(dev
)) {
496 I915_WRITE(DP_B
, dev_priv
->regfile
.saveDP_B
);
497 I915_WRITE(DP_C
, dev_priv
->regfile
.saveDP_C
);
498 I915_WRITE(DP_D
, dev_priv
->regfile
.saveDP_D
);
500 /* FIXME: restore TV & SDVO state */