diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch | 1079 |
1 files changed, 1079 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch new file mode 100644 index 0000000000..897d50c39b --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch | |||
@@ -0,0 +1,1079 @@ | |||
1 | commit a850828c640735fb410c782717c9eb7f8474e356 | ||
2 | Author: Jesse Barnes <jbarnes@virtuousgeek.org> | ||
3 | Date: Mon Aug 25 15:11:06 2008 -0700 | ||
4 | |||
5 | separate i915 suspend/resume functions into their own file | ||
6 | |||
7 | [Patch against drm-next. Consider this a trial balloon for our new Linux | ||
8 | development model.] | ||
9 | |||
10 | This is a big chunk of code. Separating it out makes it easier to change | ||
11 | without churn on the main i915_drv.c file (and there will be churn as we | ||
12 | fix bugs and add things like kernel mode setting). Also makes it easier | ||
13 | to share this file with BSD. | ||
14 | |||
15 | Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> | ||
16 | Signed-off-by: Dave Airlie <airlied@redhat.com> | ||
17 | |||
18 | diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile | ||
19 | index b032808..c4bbda6 100644 | ||
20 | --- a/drivers/gpu/drm/i915/Makefile | ||
21 | +++ b/drivers/gpu/drm/i915/Makefile | ||
22 | @@ -3,7 +3,8 @@ | ||
23 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | ||
24 | |||
25 | ccflags-y := -Iinclude/drm | ||
26 | -i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o | ||
27 | +i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \ | ||
28 | + i915_suspend.o | ||
29 | |||
30 | i915-$(CONFIG_COMPAT) += i915_ioc32.o | ||
31 | |||
32 | diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c | ||
33 | index d95eca2..eff66ed 100644 | ||
34 | --- a/drivers/gpu/drm/i915/i915_drv.c | ||
35 | +++ b/drivers/gpu/drm/i915/i915_drv.c | ||
36 | @@ -38,211 +38,9 @@ static struct pci_device_id pciidlist[] = { | ||
37 | i915_PCI_IDS | ||
38 | }; | ||
39 | |||
40 | -enum pipe { | ||
41 | - PIPE_A = 0, | ||
42 | - PIPE_B, | ||
43 | -}; | ||
44 | - | ||
45 | -static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | ||
46 | -{ | ||
47 | - struct drm_i915_private *dev_priv = dev->dev_private; | ||
48 | - | ||
49 | - if (pipe == PIPE_A) | ||
50 | - return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); | ||
51 | - else | ||
52 | - return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); | ||
53 | -} | ||
54 | - | ||
55 | -static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | ||
56 | -{ | ||
57 | - struct drm_i915_private *dev_priv = dev->dev_private; | ||
58 | - unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
59 | - u32 *array; | ||
60 | - int i; | ||
61 | - | ||
62 | - if (!i915_pipe_enabled(dev, pipe)) | ||
63 | - return; | ||
64 | - | ||
65 | - if (pipe == PIPE_A) | ||
66 | - array = dev_priv->save_palette_a; | ||
67 | - else | ||
68 | - array = dev_priv->save_palette_b; | ||
69 | - | ||
70 | - for(i = 0; i < 256; i++) | ||
71 | - array[i] = I915_READ(reg + (i << 2)); | ||
72 | -} | ||
73 | - | ||
74 | -static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | ||
75 | -{ | ||
76 | - struct drm_i915_private *dev_priv = dev->dev_private; | ||
77 | - unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
78 | - u32 *array; | ||
79 | - int i; | ||
80 | - | ||
81 | - if (!i915_pipe_enabled(dev, pipe)) | ||
82 | - return; | ||
83 | - | ||
84 | - if (pipe == PIPE_A) | ||
85 | - array = dev_priv->save_palette_a; | ||
86 | - else | ||
87 | - array = dev_priv->save_palette_b; | ||
88 | - | ||
89 | - for(i = 0; i < 256; i++) | ||
90 | - I915_WRITE(reg + (i << 2), array[i]); | ||
91 | -} | ||
92 | - | ||
93 | -static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg) | ||
94 | -{ | ||
95 | - outb(reg, index_port); | ||
96 | - return inb(data_port); | ||
97 | -} | ||
98 | - | ||
99 | -static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable) | ||
100 | -{ | ||
101 | - inb(st01); | ||
102 | - outb(palette_enable | reg, VGA_AR_INDEX); | ||
103 | - return inb(VGA_AR_DATA_READ); | ||
104 | -} | ||
105 | - | ||
106 | -static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable) | ||
107 | -{ | ||
108 | - inb(st01); | ||
109 | - outb(palette_enable | reg, VGA_AR_INDEX); | ||
110 | - outb(val, VGA_AR_DATA_WRITE); | ||
111 | -} | ||
112 | - | ||
113 | -static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val) | ||
114 | -{ | ||
115 | - outb(reg, index_port); | ||
116 | - outb(val, data_port); | ||
117 | -} | ||
118 | - | ||
119 | -static void i915_save_vga(struct drm_device *dev) | ||
120 | -{ | ||
121 | - struct drm_i915_private *dev_priv = dev->dev_private; | ||
122 | - int i; | ||
123 | - u16 cr_index, cr_data, st01; | ||
124 | - | ||
125 | - /* VGA color palette registers */ | ||
126 | - dev_priv->saveDACMASK = inb(VGA_DACMASK); | ||
127 | - /* DACCRX automatically increments during read */ | ||
128 | - outb(0, VGA_DACRX); | ||
129 | - /* Read 3 bytes of color data from each index */ | ||
130 | - for (i = 0; i < 256 * 3; i++) | ||
131 | - dev_priv->saveDACDATA[i] = inb(VGA_DACDATA); | ||
132 | - | ||
133 | - /* MSR bits */ | ||
134 | - dev_priv->saveMSR = inb(VGA_MSR_READ); | ||
135 | - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
136 | - cr_index = VGA_CR_INDEX_CGA; | ||
137 | - cr_data = VGA_CR_DATA_CGA; | ||
138 | - st01 = VGA_ST01_CGA; | ||
139 | - } else { | ||
140 | - cr_index = VGA_CR_INDEX_MDA; | ||
141 | - cr_data = VGA_CR_DATA_MDA; | ||
142 | - st01 = VGA_ST01_MDA; | ||
143 | - } | ||
144 | - | ||
145 | - /* CRT controller regs */ | ||
146 | - i915_write_indexed(cr_index, cr_data, 0x11, | ||
147 | - i915_read_indexed(cr_index, cr_data, 0x11) & | ||
148 | - (~0x80)); | ||
149 | - for (i = 0; i <= 0x24; i++) | ||
150 | - dev_priv->saveCR[i] = | ||
151 | - i915_read_indexed(cr_index, cr_data, i); | ||
152 | - /* Make sure we don't turn off CR group 0 writes */ | ||
153 | - dev_priv->saveCR[0x11] &= ~0x80; | ||
154 | - | ||
155 | - /* Attribute controller registers */ | ||
156 | - inb(st01); | ||
157 | - dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX); | ||
158 | - for (i = 0; i <= 0x14; i++) | ||
159 | - dev_priv->saveAR[i] = i915_read_ar(st01, i, 0); | ||
160 | - inb(st01); | ||
161 | - outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX); | ||
162 | - inb(st01); | ||
163 | - | ||
164 | - /* Graphics controller registers */ | ||
165 | - for (i = 0; i < 9; i++) | ||
166 | - dev_priv->saveGR[i] = | ||
167 | - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i); | ||
168 | - | ||
169 | - dev_priv->saveGR[0x10] = | ||
170 | - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10); | ||
171 | - dev_priv->saveGR[0x11] = | ||
172 | - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11); | ||
173 | - dev_priv->saveGR[0x18] = | ||
174 | - i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18); | ||
175 | - | ||
176 | - /* Sequencer registers */ | ||
177 | - for (i = 0; i < 8; i++) | ||
178 | - dev_priv->saveSR[i] = | ||
179 | - i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i); | ||
180 | -} | ||
181 | - | ||
182 | -static void i915_restore_vga(struct drm_device *dev) | ||
183 | -{ | ||
184 | - struct drm_i915_private *dev_priv = dev->dev_private; | ||
185 | - int i; | ||
186 | - u16 cr_index, cr_data, st01; | ||
187 | - | ||
188 | - /* MSR bits */ | ||
189 | - outb(dev_priv->saveMSR, VGA_MSR_WRITE); | ||
190 | - if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
191 | - cr_index = VGA_CR_INDEX_CGA; | ||
192 | - cr_data = VGA_CR_DATA_CGA; | ||
193 | - st01 = VGA_ST01_CGA; | ||
194 | - } else { | ||
195 | - cr_index = VGA_CR_INDEX_MDA; | ||
196 | - cr_data = VGA_CR_DATA_MDA; | ||
197 | - st01 = VGA_ST01_MDA; | ||
198 | - } | ||
199 | - | ||
200 | - /* Sequencer registers, don't write SR07 */ | ||
201 | - for (i = 0; i < 7; i++) | ||
202 | - i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i, | ||
203 | - dev_priv->saveSR[i]); | ||
204 | - | ||
205 | - /* CRT controller regs */ | ||
206 | - /* Enable CR group 0 writes */ | ||
207 | - i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); | ||
208 | - for (i = 0; i <= 0x24; i++) | ||
209 | - i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]); | ||
210 | - | ||
211 | - /* Graphics controller regs */ | ||
212 | - for (i = 0; i < 9; i++) | ||
213 | - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i, | ||
214 | - dev_priv->saveGR[i]); | ||
215 | - | ||
216 | - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10, | ||
217 | - dev_priv->saveGR[0x10]); | ||
218 | - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11, | ||
219 | - dev_priv->saveGR[0x11]); | ||
220 | - i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18, | ||
221 | - dev_priv->saveGR[0x18]); | ||
222 | - | ||
223 | - /* Attribute controller registers */ | ||
224 | - inb(st01); | ||
225 | - for (i = 0; i <= 0x14; i++) | ||
226 | - i915_write_ar(st01, i, dev_priv->saveAR[i], 0); | ||
227 | - inb(st01); /* switch back to index mode */ | ||
228 | - outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX); | ||
229 | - inb(st01); | ||
230 | - | ||
231 | - /* VGA color palette registers */ | ||
232 | - outb(dev_priv->saveDACMASK, VGA_DACMASK); | ||
233 | - /* DACCRX automatically increments during read */ | ||
234 | - outb(0, VGA_DACWX); | ||
235 | - /* Read 3 bytes of color data from each index */ | ||
236 | - for (i = 0; i < 256 * 3; i++) | ||
237 | - outb(dev_priv->saveDACDATA[i], VGA_DACDATA); | ||
238 | - | ||
239 | -} | ||
240 | - | ||
241 | static int i915_suspend(struct drm_device *dev, pm_message_t state) | ||
242 | { | ||
243 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
244 | - int i; | ||
245 | |||
246 | if (!dev || !dev_priv) { | ||
247 | printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); | ||
248 | @@ -254,122 +52,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | ||
249 | return 0; | ||
250 | |||
251 | pci_save_state(dev->pdev); | ||
252 | - pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
253 | - | ||
254 | - /* Display arbitration control */ | ||
255 | - dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
256 | - | ||
257 | - /* Pipe & plane A info */ | ||
258 | - dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | ||
259 | - dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | ||
260 | - dev_priv->saveFPA0 = I915_READ(FPA0); | ||
261 | - dev_priv->saveFPA1 = I915_READ(FPA1); | ||
262 | - dev_priv->saveDPLL_A = I915_READ(DPLL_A); | ||
263 | - if (IS_I965G(dev)) | ||
264 | - dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | ||
265 | - dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | ||
266 | - dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | ||
267 | - dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); | ||
268 | - dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | ||
269 | - dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | ||
270 | - dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | ||
271 | - dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
272 | - | ||
273 | - dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); | ||
274 | - dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); | ||
275 | - dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); | ||
276 | - dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); | ||
277 | - dev_priv->saveDSPAADDR = I915_READ(DSPAADDR); | ||
278 | - if (IS_I965G(dev)) { | ||
279 | - dev_priv->saveDSPASURF = I915_READ(DSPASURF); | ||
280 | - dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); | ||
281 | - } | ||
282 | - i915_save_palette(dev, PIPE_A); | ||
283 | - dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT); | ||
284 | - | ||
285 | - /* Pipe & plane B info */ | ||
286 | - dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | ||
287 | - dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | ||
288 | - dev_priv->saveFPB0 = I915_READ(FPB0); | ||
289 | - dev_priv->saveFPB1 = I915_READ(FPB1); | ||
290 | - dev_priv->saveDPLL_B = I915_READ(DPLL_B); | ||
291 | - if (IS_I965G(dev)) | ||
292 | - dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | ||
293 | - dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | ||
294 | - dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | ||
295 | - dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); | ||
296 | - dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | ||
297 | - dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | ||
298 | - dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | ||
299 | - dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
300 | - | ||
301 | - dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); | ||
302 | - dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); | ||
303 | - dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); | ||
304 | - dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); | ||
305 | - dev_priv->saveDSPBADDR = I915_READ(DSPBADDR); | ||
306 | - if (IS_I965GM(dev) || IS_IGD_GM(dev)) { | ||
307 | - dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); | ||
308 | - dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); | ||
309 | - } | ||
310 | - i915_save_palette(dev, PIPE_B); | ||
311 | - dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | ||
312 | - | ||
313 | - /* CRT state */ | ||
314 | - dev_priv->saveADPA = I915_READ(ADPA); | ||
315 | |||
316 | - /* LVDS state */ | ||
317 | - dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); | ||
318 | - dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); | ||
319 | - dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); | ||
320 | - if (IS_I965G(dev)) | ||
321 | - dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); | ||
322 | - if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
323 | - dev_priv->saveLVDS = I915_READ(LVDS); | ||
324 | - if (!IS_I830(dev) && !IS_845G(dev)) | ||
325 | - dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | ||
326 | - dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); | ||
327 | - dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); | ||
328 | - dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); | ||
329 | - | ||
330 | - /* FIXME: save TV & SDVO state */ | ||
331 | - | ||
332 | - /* FBC state */ | ||
333 | - dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); | ||
334 | - dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); | ||
335 | - dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); | ||
336 | - dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); | ||
337 | - | ||
338 | - /* Interrupt state */ | ||
339 | - dev_priv->saveIIR = I915_READ(IIR); | ||
340 | - dev_priv->saveIER = I915_READ(IER); | ||
341 | - dev_priv->saveIMR = I915_READ(IMR); | ||
342 | - | ||
343 | - /* VGA state */ | ||
344 | - dev_priv->saveVGA0 = I915_READ(VGA0); | ||
345 | - dev_priv->saveVGA1 = I915_READ(VGA1); | ||
346 | - dev_priv->saveVGA_PD = I915_READ(VGA_PD); | ||
347 | - dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | ||
348 | - | ||
349 | - /* Clock gating state */ | ||
350 | - dev_priv->saveD_STATE = I915_READ(D_STATE); | ||
351 | - dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); | ||
352 | - | ||
353 | - /* Cache mode state */ | ||
354 | - dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | ||
355 | - | ||
356 | - /* Memory Arbitration state */ | ||
357 | - dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); | ||
358 | - | ||
359 | - /* Scratch space */ | ||
360 | - for (i = 0; i < 16; i++) { | ||
361 | - dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); | ||
362 | - dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); | ||
363 | - } | ||
364 | - for (i = 0; i < 3; i++) | ||
365 | - dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | ||
366 | - | ||
367 | - i915_save_vga(dev); | ||
368 | + i915_save_state(dev); | ||
369 | |||
370 | intel_opregion_free(dev); | ||
371 | |||
372 | @@ -384,155 +68,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | ||
373 | |||
374 | static int i915_resume(struct drm_device *dev) | ||
375 | { | ||
376 | - struct drm_i915_private *dev_priv = dev->dev_private; | ||
377 | - int i; | ||
378 | - | ||
379 | pci_set_power_state(dev->pdev, PCI_D0); | ||
380 | pci_restore_state(dev->pdev); | ||
381 | if (pci_enable_device(dev->pdev)) | ||
382 | return -1; | ||
383 | pci_set_master(dev->pdev); | ||
384 | |||
385 | - pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | ||
386 | - | ||
387 | - I915_WRITE(DSPARB, dev_priv->saveDSPARB); | ||
388 | - | ||
389 | - /* Pipe & plane A info */ | ||
390 | - /* Prime the clock */ | ||
391 | - if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
392 | - I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
393 | - ~DPLL_VCO_ENABLE); | ||
394 | - udelay(150); | ||
395 | - } | ||
396 | - I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
397 | - I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
398 | - /* Actually enable it */ | ||
399 | - I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
400 | - udelay(150); | ||
401 | - if (IS_I965G(dev)) | ||
402 | - I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
403 | - udelay(150); | ||
404 | - | ||
405 | - /* Restore mode */ | ||
406 | - I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
407 | - I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
408 | - I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
409 | - I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
410 | - I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
411 | - I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
412 | - I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
413 | - | ||
414 | - /* Restore plane info */ | ||
415 | - I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
416 | - I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
417 | - I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
418 | - I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
419 | - I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
420 | - if (IS_I965G(dev)) { | ||
421 | - I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
422 | - I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
423 | - } | ||
424 | - | ||
425 | - I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
426 | - | ||
427 | - i915_restore_palette(dev, PIPE_A); | ||
428 | - /* Enable the plane */ | ||
429 | - I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
430 | - I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
431 | - | ||
432 | - /* Pipe & plane B info */ | ||
433 | - if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
434 | - I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
435 | - ~DPLL_VCO_ENABLE); | ||
436 | - udelay(150); | ||
437 | - } | ||
438 | - I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
439 | - I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
440 | - /* Actually enable it */ | ||
441 | - I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
442 | - udelay(150); | ||
443 | - if (IS_I965G(dev)) | ||
444 | - I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
445 | - udelay(150); | ||
446 | - | ||
447 | - /* Restore mode */ | ||
448 | - I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
449 | - I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
450 | - I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
451 | - I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
452 | - I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
453 | - I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
454 | - I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
455 | - | ||
456 | - /* Restore plane info */ | ||
457 | - I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
458 | - I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
459 | - I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
460 | - I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
461 | - I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
462 | - if (IS_I965G(dev)) { | ||
463 | - I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
464 | - I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
465 | - } | ||
466 | - | ||
467 | - I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
468 | - | ||
469 | - i915_restore_palette(dev, PIPE_B); | ||
470 | - /* Enable the plane */ | ||
471 | - I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
472 | - I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
473 | - | ||
474 | - /* CRT state */ | ||
475 | - I915_WRITE(ADPA, dev_priv->saveADPA); | ||
476 | - | ||
477 | - /* LVDS state */ | ||
478 | - if (IS_I965G(dev)) | ||
479 | - I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | ||
480 | - if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
481 | - I915_WRITE(LVDS, dev_priv->saveLVDS); | ||
482 | - if (!IS_I830(dev) && !IS_845G(dev)) | ||
483 | - I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | ||
484 | - | ||
485 | - I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); | ||
486 | - I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); | ||
487 | - I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); | ||
488 | - I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); | ||
489 | - I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); | ||
490 | - I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); | ||
491 | - | ||
492 | - /* FIXME: restore TV & SDVO state */ | ||
493 | - | ||
494 | - /* FBC info */ | ||
495 | - I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); | ||
496 | - I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); | ||
497 | - I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); | ||
498 | - I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); | ||
499 | - | ||
500 | - /* VGA state */ | ||
501 | - I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | ||
502 | - I915_WRITE(VGA0, dev_priv->saveVGA0); | ||
503 | - I915_WRITE(VGA1, dev_priv->saveVGA1); | ||
504 | - I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | ||
505 | - udelay(150); | ||
506 | - | ||
507 | - /* Clock gating state */ | ||
508 | - I915_WRITE (D_STATE, dev_priv->saveD_STATE); | ||
509 | - I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS); | ||
510 | - | ||
511 | - /* Cache mode state */ | ||
512 | - I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | ||
513 | - | ||
514 | - /* Memory arbitration state */ | ||
515 | - I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); | ||
516 | - | ||
517 | - for (i = 0; i < 16; i++) { | ||
518 | - I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); | ||
519 | - I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); | ||
520 | - } | ||
521 | - for (i = 0; i < 3; i++) | ||
522 | - I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | ||
523 | - | ||
524 | - i915_restore_vga(dev); | ||
525 | + i915_restore_state(dev); | ||
526 | |||
527 | intel_opregion_init(dev); | ||
528 | |||
529 | diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h | ||
530 | index e4bd01c..a82b487 100644 | ||
531 | --- a/drivers/gpu/drm/i915/i915_drv.h | ||
532 | +++ b/drivers/gpu/drm/i915/i915_drv.h | ||
533 | @@ -41,6 +41,11 @@ | ||
534 | #define DRIVER_DESC "Intel Graphics" | ||
535 | #define DRIVER_DATE "20060119" | ||
536 | |||
537 | +enum pipe { | ||
538 | + PIPE_A = 0, | ||
539 | + PIPE_B, | ||
540 | +}; | ||
541 | + | ||
542 | /* Interface history: | ||
543 | * | ||
544 | * 1.1: Original. | ||
545 | @@ -269,6 +274,10 @@ extern void i915_mem_takedown(struct mem_block **heap); | ||
546 | extern void i915_mem_release(struct drm_device * dev, | ||
547 | struct drm_file *file_priv, struct mem_block *heap); | ||
548 | |||
549 | +/* i915_suspend.c */ | ||
550 | +extern int i915_save_state(struct drm_device *dev); | ||
551 | +extern int i915_restore_state(struct drm_device *dev); | ||
552 | + | ||
553 | /* i915_opregion.c */ | ||
554 | extern int intel_opregion_init(struct drm_device *dev); | ||
555 | extern void intel_opregion_free(struct drm_device *dev); | ||
556 | @@ -279,6 +288,8 @@ extern void opregion_enable_asle(struct drm_device *dev); | ||
557 | #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val)) | ||
558 | #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg)) | ||
559 | #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val)) | ||
560 | +#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg)) | ||
561 | +#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val)) | ||
562 | |||
563 | #define I915_VERBOSE 0 | ||
564 | |||
565 | diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c | ||
566 | new file mode 100644 | ||
567 | index 0000000..e0c1fe4 | ||
568 | --- /dev/null | ||
569 | +++ b/drivers/gpu/drm/i915/i915_suspend.c | ||
570 | @@ -0,0 +1,509 @@ | ||
571 | +/* | ||
572 | + * | ||
573 | + * Copyright 2008 (c) Intel Corporation | ||
574 | + * Jesse Barnes <jbarnes@virtuousgeek.org> | ||
575 | + * | ||
576 | + * Permission is hereby granted, free of charge, to any person obtaining a | ||
577 | + * copy of this software and associated documentation files (the | ||
578 | + * "Software"), to deal in the Software without restriction, including | ||
579 | + * without limitation the rights to use, copy, modify, merge, publish, | ||
580 | + * distribute, sub license, and/or sell copies of the Software, and to | ||
581 | + * permit persons to whom the Software is furnished to do so, subject to | ||
582 | + * the following conditions: | ||
583 | + * | ||
584 | + * The above copyright notice and this permission notice (including the | ||
585 | + * next paragraph) shall be included in all copies or substantial portions | ||
586 | + * of the Software. | ||
587 | + * | ||
588 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
589 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
590 | + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
591 | + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
592 | + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
593 | + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
594 | + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
595 | + */ | ||
596 | + | ||
597 | +#include "drmP.h" | ||
598 | +#include "drm.h" | ||
599 | +#include "i915_drm.h" | ||
600 | +#include "i915_drv.h" | ||
601 | + | ||
602 | +static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | ||
603 | +{ | ||
604 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
605 | + | ||
606 | + if (pipe == PIPE_A) | ||
607 | + return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE); | ||
608 | + else | ||
609 | + return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE); | ||
610 | +} | ||
611 | + | ||
612 | +static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | ||
613 | +{ | ||
614 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
615 | + unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
616 | + u32 *array; | ||
617 | + int i; | ||
618 | + | ||
619 | + if (!i915_pipe_enabled(dev, pipe)) | ||
620 | + return; | ||
621 | + | ||
622 | + if (pipe == PIPE_A) | ||
623 | + array = dev_priv->save_palette_a; | ||
624 | + else | ||
625 | + array = dev_priv->save_palette_b; | ||
626 | + | ||
627 | + for(i = 0; i < 256; i++) | ||
628 | + array[i] = I915_READ(reg + (i << 2)); | ||
629 | +} | ||
630 | + | ||
631 | +static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | ||
632 | +{ | ||
633 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
634 | + unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B); | ||
635 | + u32 *array; | ||
636 | + int i; | ||
637 | + | ||
638 | + if (!i915_pipe_enabled(dev, pipe)) | ||
639 | + return; | ||
640 | + | ||
641 | + if (pipe == PIPE_A) | ||
642 | + array = dev_priv->save_palette_a; | ||
643 | + else | ||
644 | + array = dev_priv->save_palette_b; | ||
645 | + | ||
646 | + for(i = 0; i < 256; i++) | ||
647 | + I915_WRITE(reg + (i << 2), array[i]); | ||
648 | +} | ||
649 | + | ||
650 | +static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg) | ||
651 | +{ | ||
652 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
653 | + | ||
654 | + I915_WRITE8(index_port, reg); | ||
655 | + return I915_READ8(data_port); | ||
656 | +} | ||
657 | + | ||
658 | +static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable) | ||
659 | +{ | ||
660 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
661 | + | ||
662 | + I915_READ8(st01); | ||
663 | + I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); | ||
664 | + return I915_READ8(VGA_AR_DATA_READ); | ||
665 | +} | ||
666 | + | ||
667 | +static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable) | ||
668 | +{ | ||
669 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
670 | + | ||
671 | + I915_READ8(st01); | ||
672 | + I915_WRITE8(VGA_AR_INDEX, palette_enable | reg); | ||
673 | + I915_WRITE8(VGA_AR_DATA_WRITE, val); | ||
674 | +} | ||
675 | + | ||
676 | +static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val) | ||
677 | +{ | ||
678 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
679 | + | ||
680 | + I915_WRITE8(index_port, reg); | ||
681 | + I915_WRITE8(data_port, val); | ||
682 | +} | ||
683 | + | ||
684 | +static void i915_save_vga(struct drm_device *dev) | ||
685 | +{ | ||
686 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
687 | + int i; | ||
688 | + u16 cr_index, cr_data, st01; | ||
689 | + | ||
690 | + /* VGA color palette registers */ | ||
691 | + dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK); | ||
692 | + /* DACCRX automatically increments during read */ | ||
693 | + I915_WRITE8(VGA_DACRX, 0); | ||
694 | + /* Read 3 bytes of color data from each index */ | ||
695 | + for (i = 0; i < 256 * 3; i++) | ||
696 | + dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA); | ||
697 | + | ||
698 | + /* MSR bits */ | ||
699 | + dev_priv->saveMSR = I915_READ8(VGA_MSR_READ); | ||
700 | + if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
701 | + cr_index = VGA_CR_INDEX_CGA; | ||
702 | + cr_data = VGA_CR_DATA_CGA; | ||
703 | + st01 = VGA_ST01_CGA; | ||
704 | + } else { | ||
705 | + cr_index = VGA_CR_INDEX_MDA; | ||
706 | + cr_data = VGA_CR_DATA_MDA; | ||
707 | + st01 = VGA_ST01_MDA; | ||
708 | + } | ||
709 | + | ||
710 | + /* CRT controller regs */ | ||
711 | + i915_write_indexed(dev, cr_index, cr_data, 0x11, | ||
712 | + i915_read_indexed(dev, cr_index, cr_data, 0x11) & | ||
713 | + (~0x80)); | ||
714 | + for (i = 0; i <= 0x24; i++) | ||
715 | + dev_priv->saveCR[i] = | ||
716 | + i915_read_indexed(dev, cr_index, cr_data, i); | ||
717 | + /* Make sure we don't turn off CR group 0 writes */ | ||
718 | + dev_priv->saveCR[0x11] &= ~0x80; | ||
719 | + | ||
720 | + /* Attribute controller registers */ | ||
721 | + I915_READ8(st01); | ||
722 | + dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX); | ||
723 | + for (i = 0; i <= 0x14; i++) | ||
724 | + dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0); | ||
725 | + I915_READ8(st01); | ||
726 | + I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX); | ||
727 | + I915_READ8(st01); | ||
728 | + | ||
729 | + /* Graphics controller registers */ | ||
730 | + for (i = 0; i < 9; i++) | ||
731 | + dev_priv->saveGR[i] = | ||
732 | + i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i); | ||
733 | + | ||
734 | + dev_priv->saveGR[0x10] = | ||
735 | + i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10); | ||
736 | + dev_priv->saveGR[0x11] = | ||
737 | + i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11); | ||
738 | + dev_priv->saveGR[0x18] = | ||
739 | + i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18); | ||
740 | + | ||
741 | + /* Sequencer registers */ | ||
742 | + for (i = 0; i < 8; i++) | ||
743 | + dev_priv->saveSR[i] = | ||
744 | + i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i); | ||
745 | +} | ||
746 | + | ||
747 | +static void i915_restore_vga(struct drm_device *dev) | ||
748 | +{ | ||
749 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
750 | + int i; | ||
751 | + u16 cr_index, cr_data, st01; | ||
752 | + | ||
753 | + /* MSR bits */ | ||
754 | + I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR); | ||
755 | + if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) { | ||
756 | + cr_index = VGA_CR_INDEX_CGA; | ||
757 | + cr_data = VGA_CR_DATA_CGA; | ||
758 | + st01 = VGA_ST01_CGA; | ||
759 | + } else { | ||
760 | + cr_index = VGA_CR_INDEX_MDA; | ||
761 | + cr_data = VGA_CR_DATA_MDA; | ||
762 | + st01 = VGA_ST01_MDA; | ||
763 | + } | ||
764 | + | ||
765 | + /* Sequencer registers, don't write SR07 */ | ||
766 | + for (i = 0; i < 7; i++) | ||
767 | + i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i, | ||
768 | + dev_priv->saveSR[i]); | ||
769 | + | ||
770 | + /* CRT controller regs */ | ||
771 | + /* Enable CR group 0 writes */ | ||
772 | + i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]); | ||
773 | + for (i = 0; i <= 0x24; i++) | ||
774 | + i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]); | ||
775 | + | ||
776 | + /* Graphics controller regs */ | ||
777 | + for (i = 0; i < 9; i++) | ||
778 | + i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i, | ||
779 | + dev_priv->saveGR[i]); | ||
780 | + | ||
781 | + i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10, | ||
782 | + dev_priv->saveGR[0x10]); | ||
783 | + i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11, | ||
784 | + dev_priv->saveGR[0x11]); | ||
785 | + i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18, | ||
786 | + dev_priv->saveGR[0x18]); | ||
787 | + | ||
788 | + /* Attribute controller registers */ | ||
789 | + I915_READ8(st01); /* switch back to index mode */ | ||
790 | + for (i = 0; i <= 0x14; i++) | ||
791 | + i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0); | ||
792 | + I915_READ8(st01); /* switch back to index mode */ | ||
793 | + I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20); | ||
794 | + I915_READ8(st01); | ||
795 | + | ||
796 | + /* VGA color palette registers */ | ||
797 | + I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); | ||
798 | + /* DACCRX automatically increments during read */ | ||
799 | + I915_WRITE8(VGA_DACWX, 0); | ||
800 | + /* Read 3 bytes of color data from each index */ | ||
801 | + for (i = 0; i < 256 * 3; i++) | ||
802 | + I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]); | ||
803 | + | ||
804 | +} | ||
805 | + | ||
806 | +int i915_save_state(struct drm_device *dev) | ||
807 | +{ | ||
808 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
809 | + int i; | ||
810 | + | ||
811 | + pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
812 | + | ||
813 | + /* Display arbitration control */ | ||
814 | + dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
815 | + | ||
816 | + /* Pipe & plane A info */ | ||
817 | + dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | ||
818 | + dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | ||
819 | + dev_priv->saveFPA0 = I915_READ(FPA0); | ||
820 | + dev_priv->saveFPA1 = I915_READ(FPA1); | ||
821 | + dev_priv->saveDPLL_A = I915_READ(DPLL_A); | ||
822 | + if (IS_I965G(dev)) | ||
823 | + dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | ||
824 | + dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | ||
825 | + dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | ||
826 | + dev_priv->saveHSYNC_A = I915_READ(HSYNC_A); | ||
827 | + dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | ||
828 | + dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | ||
829 | + dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | ||
830 | + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
831 | + | ||
832 | + dev_priv->saveDSPACNTR = I915_READ(DSPACNTR); | ||
833 | + dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE); | ||
834 | + dev_priv->saveDSPASIZE = I915_READ(DSPASIZE); | ||
835 | + dev_priv->saveDSPAPOS = I915_READ(DSPAPOS); | ||
836 | + dev_priv->saveDSPAADDR = I915_READ(DSPAADDR); | ||
837 | + if (IS_I965G(dev)) { | ||
838 | + dev_priv->saveDSPASURF = I915_READ(DSPASURF); | ||
839 | + dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF); | ||
840 | + } | ||
841 | + i915_save_palette(dev, PIPE_A); | ||
842 | + dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT); | ||
843 | + | ||
844 | + /* Pipe & plane B info */ | ||
845 | + dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | ||
846 | + dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | ||
847 | + dev_priv->saveFPB0 = I915_READ(FPB0); | ||
848 | + dev_priv->saveFPB1 = I915_READ(FPB1); | ||
849 | + dev_priv->saveDPLL_B = I915_READ(DPLL_B); | ||
850 | + if (IS_I965G(dev)) | ||
851 | + dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | ||
852 | + dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | ||
853 | + dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | ||
854 | + dev_priv->saveHSYNC_B = I915_READ(HSYNC_B); | ||
855 | + dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | ||
856 | + dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | ||
857 | + dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | ||
858 | + dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | ||
859 | + | ||
860 | + dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR); | ||
861 | + dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE); | ||
862 | + dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE); | ||
863 | + dev_priv->saveDSPBPOS = I915_READ(DSPBPOS); | ||
864 | + dev_priv->saveDSPBADDR = I915_READ(DSPBADDR); | ||
865 | + if (IS_I965GM(dev) || IS_IGD_GM(dev)) { | ||
866 | + dev_priv->saveDSPBSURF = I915_READ(DSPBSURF); | ||
867 | + dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF); | ||
868 | + } | ||
869 | + i915_save_palette(dev, PIPE_B); | ||
870 | + dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | ||
871 | + | ||
872 | + /* CRT state */ | ||
873 | + dev_priv->saveADPA = I915_READ(ADPA); | ||
874 | + | ||
875 | + /* LVDS state */ | ||
876 | + dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL); | ||
877 | + dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS); | ||
878 | + dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); | ||
879 | + if (IS_I965G(dev)) | ||
880 | + dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); | ||
881 | + if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
882 | + dev_priv->saveLVDS = I915_READ(LVDS); | ||
883 | + if (!IS_I830(dev) && !IS_845G(dev)) | ||
884 | + dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | ||
885 | + dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS); | ||
886 | + dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); | ||
887 | + dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); | ||
888 | + | ||
889 | + /* FIXME: save TV & SDVO state */ | ||
890 | + | ||
891 | + /* FBC state */ | ||
892 | + dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE); | ||
893 | + dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE); | ||
894 | + dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); | ||
895 | + dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); | ||
896 | + | ||
897 | + /* Interrupt state */ | ||
898 | + dev_priv->saveIIR = I915_READ(IIR); | ||
899 | + dev_priv->saveIER = I915_READ(IER); | ||
900 | + dev_priv->saveIMR = I915_READ(IMR); | ||
901 | + | ||
902 | + /* VGA state */ | ||
903 | + dev_priv->saveVGA0 = I915_READ(VGA0); | ||
904 | + dev_priv->saveVGA1 = I915_READ(VGA1); | ||
905 | + dev_priv->saveVGA_PD = I915_READ(VGA_PD); | ||
906 | + dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | ||
907 | + | ||
908 | + /* Clock gating state */ | ||
909 | + dev_priv->saveD_STATE = I915_READ(D_STATE); | ||
910 | + dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); | ||
911 | + | ||
912 | + /* Cache mode state */ | ||
913 | + dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); | ||
914 | + | ||
915 | + /* Memory Arbitration state */ | ||
916 | + dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); | ||
917 | + | ||
918 | + /* Scratch space */ | ||
919 | + for (i = 0; i < 16; i++) { | ||
920 | + dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); | ||
921 | + dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); | ||
922 | + } | ||
923 | + for (i = 0; i < 3; i++) | ||
924 | + dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | ||
925 | + | ||
926 | + i915_save_vga(dev); | ||
927 | + | ||
928 | + return 0; | ||
929 | +} | ||
930 | + | ||
931 | +int i915_restore_state(struct drm_device *dev) | ||
932 | +{ | ||
933 | + struct drm_i915_private *dev_priv = dev->dev_private; | ||
934 | + int i; | ||
935 | + | ||
936 | + pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | ||
937 | + | ||
938 | + I915_WRITE(DSPARB, dev_priv->saveDSPARB); | ||
939 | + | ||
940 | + /* Pipe & plane A info */ | ||
941 | + /* Prime the clock */ | ||
942 | + if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
943 | + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
944 | + ~DPLL_VCO_ENABLE); | ||
945 | + DRM_UDELAY(150); | ||
946 | + } | ||
947 | + I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
948 | + I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
949 | + /* Actually enable it */ | ||
950 | + I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
951 | + DRM_UDELAY(150); | ||
952 | + if (IS_I965G(dev)) | ||
953 | + I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
954 | + DRM_UDELAY(150); | ||
955 | + | ||
956 | + /* Restore mode */ | ||
957 | + I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
958 | + I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
959 | + I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
960 | + I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
961 | + I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
962 | + I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
963 | + I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
964 | + | ||
965 | + /* Restore plane info */ | ||
966 | + I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
967 | + I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
968 | + I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
969 | + I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
970 | + I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
971 | + if (IS_I965G(dev)) { | ||
972 | + I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
973 | + I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
974 | + } | ||
975 | + | ||
976 | + I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
977 | + | ||
978 | + i915_restore_palette(dev, PIPE_A); | ||
979 | + /* Enable the plane */ | ||
980 | + I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
981 | + I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
982 | + | ||
983 | + /* Pipe & plane B info */ | ||
984 | + if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
985 | + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
986 | + ~DPLL_VCO_ENABLE); | ||
987 | + DRM_UDELAY(150); | ||
988 | + } | ||
989 | + I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
990 | + I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
991 | + /* Actually enable it */ | ||
992 | + I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
993 | + DRM_UDELAY(150); | ||
994 | + if (IS_I965G(dev)) | ||
995 | + I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
996 | + DRM_UDELAY(150); | ||
997 | + | ||
998 | + /* Restore mode */ | ||
999 | + I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
1000 | + I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
1001 | + I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
1002 | + I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
1003 | + I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
1004 | + I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
1005 | + I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
1006 | + | ||
1007 | + /* Restore plane info */ | ||
1008 | + I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
1009 | + I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
1010 | + I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
1011 | + I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
1012 | + I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
1013 | + if (IS_I965G(dev)) { | ||
1014 | + I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
1015 | + I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
1016 | + } | ||
1017 | + | ||
1018 | + I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
1019 | + | ||
1020 | + i915_restore_palette(dev, PIPE_B); | ||
1021 | + /* Enable the plane */ | ||
1022 | + I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
1023 | + I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
1024 | + | ||
1025 | + /* CRT state */ | ||
1026 | + I915_WRITE(ADPA, dev_priv->saveADPA); | ||
1027 | + | ||
1028 | + /* LVDS state */ | ||
1029 | + if (IS_I965G(dev)) | ||
1030 | + I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | ||
1031 | + if (IS_MOBILE(dev) && !IS_I830(dev)) | ||
1032 | + I915_WRITE(LVDS, dev_priv->saveLVDS); | ||
1033 | + if (!IS_I830(dev) && !IS_845G(dev)) | ||
1034 | + I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | ||
1035 | + | ||
1036 | + I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS); | ||
1037 | + I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL); | ||
1038 | + I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); | ||
1039 | + I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); | ||
1040 | + I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); | ||
1041 | + I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); | ||
1042 | + | ||
1043 | + /* FIXME: restore TV & SDVO state */ | ||
1044 | + | ||
1045 | + /* FBC info */ | ||
1046 | + I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE); | ||
1047 | + I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE); | ||
1048 | + I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2); | ||
1049 | + I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL); | ||
1050 | + | ||
1051 | + /* VGA state */ | ||
1052 | + I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | ||
1053 | + I915_WRITE(VGA0, dev_priv->saveVGA0); | ||
1054 | + I915_WRITE(VGA1, dev_priv->saveVGA1); | ||
1055 | + I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | ||
1056 | + DRM_UDELAY(150); | ||
1057 | + | ||
1058 | + /* Clock gating state */ | ||
1059 | + I915_WRITE (D_STATE, dev_priv->saveD_STATE); | ||
1060 | + I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); | ||
1061 | + | ||
1062 | + /* Cache mode state */ | ||
1063 | + I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | ||
1064 | + | ||
1065 | + /* Memory arbitration state */ | ||
1066 | + I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000); | ||
1067 | + | ||
1068 | + for (i = 0; i < 16; i++) { | ||
1069 | + I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]); | ||
1070 | + I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]); | ||
1071 | + } | ||
1072 | + for (i = 0; i < 3; i++) | ||
1073 | + I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | ||
1074 | + | ||
1075 | + i915_restore_vga(dev); | ||
1076 | + | ||
1077 | + return 0; | ||
1078 | +} | ||
1079 | + | ||