Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/drm/i915_drv.c
+++ new/usr/src/uts/intel/io/drm/i915_drv.c
1 1 /* BEGIN CSTYLED */
2 2
3 3 /*
4 4 * i915_drv.c -- Intel i915 driver -*- linux-c -*-
5 5 * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
6 6 */
7 7
8 8 /*
9 9 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
10 10 * Copyright (c) 2009, Intel Corporation.
11 11 * All Rights Reserved.
12 12 *
13 13 * Permission is hereby granted, free of charge, to any person obtaining a
14 14 * copy of this software and associated documentation files (the "Software"),
15 15 * to deal in the Software without restriction, including without limitation
16 16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 17 * and/or sell copies of the Software, and to permit persons to whom the
18 18 * Software is furnished to do so, subject to the following conditions:
19 19 *
20 20 * The above copyright notice and this permission notice (including the next
21 21 * paragraph) shall be included in all copies or substantial portions of the
22 22 * Software.
23 23 *
24 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 27 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
28 28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29 29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 30 * OTHER DEALINGS IN THE SOFTWARE.
31 31 *
32 32 * Authors:
33 33 * Gareth Hughes <gareth@valinux.com>
34 34 *
35 35 */
36 36
37 37 /*
38 38 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
39 39 * Use is subject to license terms.
40 40 */
41 41
42 42 /*
43 43 * I915 DRM Driver for Solaris
44 44 *
45 45 * This driver provides the hardware 3D acceleration support for Intel
46 46 * integrated video devices (e.g. i8xx/i915/i945 series chipsets), under the
47 47 * DRI (Direct Rendering Infrastructure). DRM (Direct Rendering Manager) here
48 48 * means the kernel device driver in DRI.
49 49 *
50 50 * I915 driver is a device dependent driver only, it depends on a misc module
51 51 * named drm for generic DRM operations.
52 52 */
53 53
54 54 #include "drmP.h"
55 55 #include "i915_drm.h"
56 56 #include "i915_drv.h"
57 57 #include "drm_pciids.h"
58 58
59 59 /*
60 60 * copied from vgasubr.h
61 61 */
62 62
63 63 struct vgaregmap {
64 64 uint8_t *addr;
65 65 ddi_acc_handle_t handle;
66 66 boolean_t mapped;
67 67 };
68 68
69 69 enum pipe {
70 70 PIPE_A = 0,
71 71 PIPE_B,
72 72 };
73 73
74 74
75 75 /*
76 76 * cb_ops entrypoint
77 77 */
78 78 extern struct cb_ops drm_cb_ops;
79 79
80 80 /*
81 81 * module entrypoint
82 82 */
83 83 static int i915_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
84 84 static int i915_attach(dev_info_t *, ddi_attach_cmd_t);
85 85 static int i915_detach(dev_info_t *, ddi_detach_cmd_t);
86 86
87 87
88 88 /* drv_PCI_IDs comes from drm_pciids.h */
89 89 static drm_pci_id_list_t i915_pciidlist[] = {
90 90 i915_PCI_IDS
91 91 };
92 92
93 93 /*
94 94 * Local routines
95 95 */
96 96 static void i915_configure(drm_driver_t *);
97 97 static int i915_quiesce(dev_info_t *dip);
98 98
99 99 /*
100 100 * DRM driver
101 101 */
102 102 static drm_driver_t i915_driver = {0};
103 103
104 104
105 105 static struct dev_ops i915_dev_ops = {
106 106 DEVO_REV, /* devo_rev */
107 107 0, /* devo_refcnt */
108 108 i915_info, /* devo_getinfo */
109 109 nulldev, /* devo_identify */
110 110 nulldev, /* devo_probe */
111 111 i915_attach, /* devo_attach */
112 112 i915_detach, /* devo_detach */
113 113 nodev, /* devo_reset */
114 114 &drm_cb_ops, /* devo_cb_ops */
115 115 NULL, /* devo_bus_ops */
116 116 NULL, /* power */
↓ open down ↓ |
116 lines elided |
↑ open up ↑ |
117 117 i915_quiesce, /* devo_quiesce */
118 118 };
119 119
120 120 static struct modldrv modldrv = {
121 121 &mod_driverops, /* drv_modops */
122 122 "I915 DRM driver", /* drv_linkinfo */
123 123 &i915_dev_ops, /* drv_dev_ops */
124 124 };
125 125
126 126 static struct modlinkage modlinkage = {
127 - MODREV_1, (void *) &modldrv, NULL
127 + MODREV_1, { (void *) &modldrv, NULL }
128 128 };
129 129
130 130 static ddi_device_acc_attr_t s3_attr = {
131 131 DDI_DEVICE_ATTR_V0,
132 132 DDI_NEVERSWAP_ACC,
133 133 DDI_STRICTORDER_ACC /* must be DDI_STRICTORDER_ACC */
134 134 };
135 135
136 136 /*
137 137 * softstate head
138 138 */
139 139 static void *i915_statep;
140 140
141 141 int
142 142 _init(void)
143 143 {
144 144 int error;
145 145
146 146 i915_configure(&i915_driver);
147 147
148 148 if ((error = ddi_soft_state_init(&i915_statep,
149 149 sizeof (drm_device_t), DRM_MAX_INSTANCES)) != 0)
150 150 return (error);
151 151
152 152 if ((error = mod_install(&modlinkage)) != 0) {
153 153 ddi_soft_state_fini(&i915_statep);
154 154 return (error);
155 155 }
156 156
157 157 return (error);
158 158
159 159 } /* _init() */
160 160
161 161 int
162 162 _fini(void)
163 163 {
164 164 int error;
165 165
166 166 if ((error = mod_remove(&modlinkage)) != 0)
167 167 return (error);
168 168
169 169 (void) ddi_soft_state_fini(&i915_statep);
170 170
171 171 return (0);
172 172
173 173 } /* _fini() */
174 174
175 175 int
176 176 _info(struct modinfo *modinfop)
177 177 {
178 178 return (mod_info(&modlinkage, modinfop));
179 179
180 180 } /* _info() */
181 181
182 182 /*
183 183 * off range: 0x3b0 ~ 0x3ff
184 184 */
185 185
186 186 static void
187 187 vga_reg_put8(struct vgaregmap *regmap, uint16_t off, uint8_t val)
188 188 {
189 189 ASSERT((off >= 0x3b0) && (off <= 0x3ff));
190 190
191 191 ddi_put8(regmap->handle, regmap->addr + off, val);
192 192 }
193 193
194 194 /*
195 195 * off range: 0x3b0 ~ 0x3ff
196 196 */
197 197 static uint8_t
198 198 vga_reg_get8(struct vgaregmap *regmap, uint16_t off)
199 199 {
200 200
201 201 ASSERT((off >= 0x3b0) && (off <= 0x3ff));
202 202
203 203 return (ddi_get8(regmap->handle, regmap->addr + off));
204 204 }
205 205
206 206 static void
207 207 i915_write_indexed(struct vgaregmap *regmap,
208 208 uint16_t index_port, uint16_t data_port, uint8_t index, uint8_t val)
209 209 {
210 210 vga_reg_put8(regmap, index_port, index);
211 211 vga_reg_put8(regmap, data_port, val);
212 212 }
213 213
214 214 static uint8_t
215 215 i915_read_indexed(struct vgaregmap *regmap,
216 216 uint16_t index_port, uint16_t data_port, uint8_t index)
217 217 {
218 218 vga_reg_put8(regmap, index_port, index);
219 219 return (vga_reg_get8(regmap, data_port));
220 220 }
221 221
222 222 static void
223 223 i915_write_ar(struct vgaregmap *regmap, uint16_t st01,
224 224 uint8_t reg, uint8_t val, uint8_t palette_enable)
225 225 {
226 226 (void) vga_reg_get8(regmap, st01);
227 227 vga_reg_put8(regmap, VGA_AR_INDEX, palette_enable | reg);
228 228 vga_reg_put8(regmap, VGA_AR_DATA_WRITE, val);
229 229 }
230 230
231 231 static uint8_t
232 232 i915_read_ar(struct vgaregmap *regmap, uint16_t st01,
233 233 uint8_t index, uint8_t palette_enable)
234 234 {
235 235 (void) vga_reg_get8(regmap, st01);
236 236 vga_reg_put8(regmap, VGA_AR_INDEX, index | palette_enable);
237 237 return (vga_reg_get8(regmap, VGA_AR_DATA_READ));
238 238 }
239 239
240 240 static int
241 241 i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
242 242 {
243 243 struct s3_i915_private *s3_priv = dev->s3_private;
244 244
245 245 if (pipe == PIPE_A)
246 246 return (S3_READ(DPLL_A) & DPLL_VCO_ENABLE);
247 247 else
248 248 return (S3_READ(DPLL_B) & DPLL_VCO_ENABLE);
249 249 }
250 250
251 251 static void
252 252 i915_save_palette(struct drm_device *dev, enum pipe pipe)
253 253 {
254 254 struct s3_i915_private *s3_priv = dev->s3_private;
255 255 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
256 256 uint32_t *array;
257 257 int i;
258 258
259 259 if (!i915_pipe_enabled(dev, pipe))
260 260 return;
261 261
262 262 if (pipe == PIPE_A)
263 263 array = s3_priv->save_palette_a;
264 264 else
265 265 array = s3_priv->save_palette_b;
266 266
267 267 for(i = 0; i < 256; i++)
268 268 array[i] = S3_READ(reg + (i << 2));
269 269
270 270 }
271 271
272 272 static void
273 273 i915_restore_palette(struct drm_device *dev, enum pipe pipe)
274 274 {
275 275 struct s3_i915_private *s3_priv = dev->s3_private;
276 276 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
277 277 uint32_t *array;
278 278 int i;
279 279
280 280 if (!i915_pipe_enabled(dev, pipe))
281 281 return;
282 282
283 283 if (pipe == PIPE_A)
284 284 array = s3_priv->save_palette_a;
285 285 else
286 286 array = s3_priv->save_palette_b;
287 287
288 288 for(i = 0; i < 256; i++)
289 289 S3_WRITE(reg + (i << 2), array[i]);
290 290 }
291 291
292 292 static void
293 293 i915_save_vga(struct drm_device *dev)
294 294 {
295 295 struct s3_i915_private *s3_priv = dev->s3_private;
296 296 int i;
297 297 uint16_t cr_index, cr_data, st01;
298 298 struct vgaregmap regmap;
299 299
300 300 regmap.addr = (uint8_t *)s3_priv->saveAddr;
301 301 regmap.handle = s3_priv->saveHandle;
302 302
303 303 /* VGA color palette registers */
304 304 s3_priv->saveDACMASK = vga_reg_get8(®map, VGA_DACMASK);
305 305 /* DACCRX automatically increments during read */
306 306 vga_reg_put8(®map, VGA_DACRX, 0);
307 307 /* Read 3 bytes of color data from each index */
308 308 for (i = 0; i < 256 * 3; i++)
309 309 s3_priv->saveDACDATA[i] = vga_reg_get8(®map, VGA_DACDATA);
310 310
311 311 /* MSR bits */
312 312 s3_priv->saveMSR = vga_reg_get8(®map, VGA_MSR_READ);
313 313 if (s3_priv->saveMSR & VGA_MSR_CGA_MODE) {
314 314 cr_index = VGA_CR_INDEX_CGA;
315 315 cr_data = VGA_CR_DATA_CGA;
316 316 st01 = VGA_ST01_CGA;
317 317 } else {
318 318 cr_index = VGA_CR_INDEX_MDA;
319 319 cr_data = VGA_CR_DATA_MDA;
320 320 st01 = VGA_ST01_MDA;
321 321 }
322 322
323 323 /* CRT controller regs */
324 324 i915_write_indexed(®map, cr_index, cr_data, 0x11,
325 325 i915_read_indexed(®map, cr_index, cr_data, 0x11) & (~0x80));
326 326 for (i = 0; i <= 0x24; i++)
327 327 s3_priv->saveCR[i] =
328 328 i915_read_indexed(®map, cr_index, cr_data, i);
329 329 /* Make sure we don't turn off CR group 0 writes */
330 330 s3_priv->saveCR[0x11] &= ~0x80;
331 331
332 332 /* Attribute controller registers */
333 333 (void) vga_reg_get8(®map, st01);
334 334 s3_priv->saveAR_INDEX = vga_reg_get8(®map, VGA_AR_INDEX);
335 335 for (i = 0; i <= 0x14; i++)
336 336 s3_priv->saveAR[i] = i915_read_ar(®map, st01, i, 0);
337 337 (void) vga_reg_get8(®map, st01);
338 338 vga_reg_put8(®map, VGA_AR_INDEX, s3_priv->saveAR_INDEX);
339 339 (void) vga_reg_get8(®map, st01);
340 340
341 341 /* Graphics controller registers */
342 342 for (i = 0; i < 9; i++)
343 343 s3_priv->saveGR[i] =
344 344 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, i);
345 345
346 346 s3_priv->saveGR[0x10] =
347 347 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
348 348 s3_priv->saveGR[0x11] =
349 349 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
350 350 s3_priv->saveGR[0x18] =
351 351 i915_read_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
352 352
353 353 /* Sequencer registers */
354 354 for (i = 0; i < 8; i++)
355 355 s3_priv->saveSR[i] =
356 356 i915_read_indexed(®map, VGA_SR_INDEX, VGA_SR_DATA, i);
357 357 }
358 358
359 359 static void
360 360 i915_restore_vga(struct drm_device *dev)
361 361 {
362 362 struct s3_i915_private *s3_priv = dev->s3_private;
363 363 int i;
364 364 uint16_t cr_index, cr_data, st01;
365 365 struct vgaregmap regmap;
366 366
367 367 regmap.addr = (uint8_t *)s3_priv->saveAddr;
368 368 regmap.handle = s3_priv->saveHandle;
369 369
370 370 /*
371 371 * I/O Address Select. This bit selects 3Bxh or 3Dxh as the
372 372 * I/O address for the CRT Controller registers,
373 373 * the Feature Control Register (FCR), and Input Status Register
374 374 * 1 (ST01). Presently ignored (whole range is claimed), but
375 375 * will "ignore" 3Bx for color configuration or 3Dx for monochrome.
376 376 * Note that it is typical in AGP chipsets to shadow this bit
377 377 * and properly steer I/O cycles to the proper bus for operation
378 378 * where a MDA exists on another bus such as ISA.
379 379 * 0 = Select 3Bxh I/O address (MDA emulation) (default).
380 380 * 1 = Select 3Dxh I/O address (CGA emulation).
381 381 */
382 382 vga_reg_put8(®map, VGA_MSR_WRITE, s3_priv->saveMSR);
383 383
384 384 if (s3_priv->saveMSR & VGA_MSR_CGA_MODE) {
385 385 cr_index = VGA_CR_INDEX_CGA;
386 386 cr_data = VGA_CR_DATA_CGA;
387 387 st01 = VGA_ST01_CGA;
388 388 } else {
389 389 cr_index = VGA_CR_INDEX_MDA;
390 390 cr_data = VGA_CR_DATA_MDA;
391 391 st01 = VGA_ST01_MDA;
392 392 }
393 393
394 394 /* Sequencer registers, don't write SR07 */
395 395 for (i = 0; i < 7; i++)
396 396 i915_write_indexed(®map, VGA_SR_INDEX, VGA_SR_DATA, i,
397 397 s3_priv->saveSR[i]);
398 398 /* CRT controller regs */
399 399 /* Enable CR group 0 writes */
400 400 i915_write_indexed(®map, cr_index, cr_data,
401 401 0x11, s3_priv->saveCR[0x11]);
402 402 for (i = 0; i <= 0x24; i++)
403 403 i915_write_indexed(®map, cr_index,
404 404 cr_data, i, s3_priv->saveCR[i]);
405 405
406 406 /* Graphics controller regs */
407 407 for (i = 0; i < 9; i++)
408 408 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, i,
409 409 s3_priv->saveGR[i]);
410 410
411 411 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
412 412 s3_priv->saveGR[0x10]);
413 413 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
414 414 s3_priv->saveGR[0x11]);
415 415 i915_write_indexed(®map, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
416 416 s3_priv->saveGR[0x18]);
417 417
418 418 /* Attribute controller registers */
419 419 (void) vga_reg_get8(®map, st01); /* switch back to index mode */
420 420 for (i = 0; i <= 0x14; i++)
421 421 i915_write_ar(®map, st01, i, s3_priv->saveAR[i], 0);
422 422 (void) vga_reg_get8(®map, st01); /* switch back to index mode */
423 423 vga_reg_put8(®map, VGA_AR_INDEX, s3_priv->saveAR_INDEX | 0x20);
424 424 (void) vga_reg_get8(®map, st01); /* switch back to index mode */
425 425
426 426 /* VGA color palette registers */
427 427 vga_reg_put8(®map, VGA_DACMASK, s3_priv->saveDACMASK);
428 428 /* DACCRX automatically increments during read */
429 429 vga_reg_put8(®map, VGA_DACWX, 0);
430 430 /* Read 3 bytes of color data from each index */
431 431 for (i = 0; i < 256 * 3; i++)
432 432 vga_reg_put8(®map, VGA_DACDATA, s3_priv->saveDACDATA[i]);
433 433 }
434 434
435 435 /**
436 436 * i915_save_display - save display & mode info
437 437 * @dev: DRM device
438 438 *
439 439 * Save mode timings and display info.
440 440 */
441 441 void i915_save_display(struct drm_device *dev)
442 442 {
443 443 struct s3_i915_private *s3_priv = dev->s3_private;
444 444
445 445 /* Display arbitration control */
446 446 s3_priv->saveDSPARB = S3_READ(DSPARB);
447 447
448 448 /*
449 449 * Pipe & plane A info.
450 450 */
451 451 s3_priv->savePIPEACONF = S3_READ(PIPEACONF);
452 452 s3_priv->savePIPEASRC = S3_READ(PIPEASRC);
453 453 s3_priv->saveFPA0 = S3_READ(FPA0);
454 454 s3_priv->saveFPA1 = S3_READ(FPA1);
455 455 s3_priv->saveDPLL_A = S3_READ(DPLL_A);
456 456 if (IS_I965G(dev))
457 457 s3_priv->saveDPLL_A_MD = S3_READ(DPLL_A_MD);
458 458 s3_priv->saveHTOTAL_A = S3_READ(HTOTAL_A);
459 459 s3_priv->saveHBLANK_A = S3_READ(HBLANK_A);
460 460 s3_priv->saveHSYNC_A = S3_READ(HSYNC_A);
461 461 s3_priv->saveVTOTAL_A = S3_READ(VTOTAL_A);
462 462 s3_priv->saveVBLANK_A = S3_READ(VBLANK_A);
463 463 s3_priv->saveVSYNC_A = S3_READ(VSYNC_A);
464 464 s3_priv->saveBCLRPAT_A = S3_READ(BCLRPAT_A);
465 465
466 466 s3_priv->saveDSPACNTR = S3_READ(DSPACNTR);
467 467 s3_priv->saveDSPASTRIDE = S3_READ(DSPASTRIDE);
468 468 s3_priv->saveDSPASIZE = S3_READ(DSPASIZE);
469 469 s3_priv->saveDSPAPOS = S3_READ(DSPAPOS);
470 470 s3_priv->saveDSPABASE = S3_READ(DSPABASE);
471 471 if (IS_I965G(dev)) {
472 472 s3_priv->saveDSPASURF = S3_READ(DSPASURF);
473 473 s3_priv->saveDSPATILEOFF = S3_READ(DSPATILEOFF);
474 474 }
475 475 i915_save_palette(dev, PIPE_A);
476 476 s3_priv->savePIPEASTAT = S3_READ(PIPEASTAT);
477 477
478 478 /*
479 479 * Pipe & plane B info
480 480 */
481 481 s3_priv->savePIPEBCONF = S3_READ(PIPEBCONF);
482 482 s3_priv->savePIPEBSRC = S3_READ(PIPEBSRC);
483 483 s3_priv->saveFPB0 = S3_READ(FPB0);
484 484 s3_priv->saveFPB1 = S3_READ(FPB1);
485 485 s3_priv->saveDPLL_B = S3_READ(DPLL_B);
486 486 if (IS_I965G(dev))
487 487 s3_priv->saveDPLL_B_MD = S3_READ(DPLL_B_MD);
488 488 s3_priv->saveHTOTAL_B = S3_READ(HTOTAL_B);
489 489 s3_priv->saveHBLANK_B = S3_READ(HBLANK_B);
490 490 s3_priv->saveHSYNC_B = S3_READ(HSYNC_B);
491 491 s3_priv->saveVTOTAL_B = S3_READ(VTOTAL_B);
492 492 s3_priv->saveVBLANK_B = S3_READ(VBLANK_B);
493 493 s3_priv->saveVSYNC_B = S3_READ(VSYNC_B);
494 494 s3_priv->saveBCLRPAT_A = S3_READ(BCLRPAT_A);
495 495
496 496 s3_priv->saveDSPBCNTR = S3_READ(DSPBCNTR);
497 497 s3_priv->saveDSPBSTRIDE = S3_READ(DSPBSTRIDE);
498 498 s3_priv->saveDSPBSIZE = S3_READ(DSPBSIZE);
499 499 s3_priv->saveDSPBPOS = S3_READ(DSPBPOS);
500 500 s3_priv->saveDSPBBASE = S3_READ(DSPBBASE);
501 501 if (IS_I965GM(dev) || IS_GM45(dev)) {
502 502 s3_priv->saveDSPBSURF = S3_READ(DSPBSURF);
503 503 s3_priv->saveDSPBTILEOFF = S3_READ(DSPBTILEOFF);
504 504 }
505 505 i915_save_palette(dev, PIPE_B);
506 506 s3_priv->savePIPEBSTAT = S3_READ(PIPEBSTAT);
507 507
508 508 /*
509 509 * CRT state
510 510 */
511 511 s3_priv->saveADPA = S3_READ(ADPA);
512 512
513 513 /*
514 514 * LVDS state
515 515 */
516 516 s3_priv->savePP_CONTROL = S3_READ(PP_CONTROL);
517 517 s3_priv->savePFIT_PGM_RATIOS = S3_READ(PFIT_PGM_RATIOS);
518 518 s3_priv->saveBLC_PWM_CTL = S3_READ(BLC_PWM_CTL);
519 519 if (IS_I965G(dev))
520 520 s3_priv->saveBLC_PWM_CTL2 = S3_READ(BLC_PWM_CTL2);
521 521 if (IS_MOBILE(dev) && !IS_I830(dev))
522 522 s3_priv->saveLVDS = S3_READ(LVDS);
523 523 if (!IS_I830(dev) && !IS_845G(dev))
524 524 s3_priv->savePFIT_CONTROL = S3_READ(PFIT_CONTROL);
525 525 s3_priv->saveLVDSPP_ON = S3_READ(LVDSPP_ON);
526 526 s3_priv->saveLVDSPP_OFF = S3_READ(LVDSPP_OFF);
527 527 s3_priv->savePP_CYCLE = S3_READ(PP_CYCLE);
528 528
529 529 /* FIXME: save TV & SDVO state */
530 530
531 531 /* FBC state */
532 532 s3_priv->saveFBC_CFB_BASE = S3_READ(FBC_CFB_BASE);
533 533 s3_priv->saveFBC_LL_BASE = S3_READ(FBC_LL_BASE);
534 534 s3_priv->saveFBC_CONTROL2 = S3_READ(FBC_CONTROL2);
535 535 s3_priv->saveFBC_CONTROL = S3_READ(FBC_CONTROL);
536 536
537 537 /* VGA state */
538 538 s3_priv->saveVCLK_DIVISOR_VGA0 = S3_READ(VCLK_DIVISOR_VGA0);
539 539 s3_priv->saveVCLK_DIVISOR_VGA1 = S3_READ(VCLK_DIVISOR_VGA1);
540 540 s3_priv->saveVCLK_POST_DIV = S3_READ(VCLK_POST_DIV);
541 541 s3_priv->saveVGACNTRL = S3_READ(VGACNTRL);
542 542
543 543 i915_save_vga(dev);
544 544 }
545 545
546 546 void i915_restore_display(struct drm_device *dev)
547 547 {
548 548 struct s3_i915_private *s3_priv = dev->s3_private;
549 549
550 550 S3_WRITE(DSPARB, s3_priv->saveDSPARB);
551 551
552 552 /*
553 553 * Pipe & plane A info
554 554 * Prime the clock
555 555 */
556 556 if (s3_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
557 557 S3_WRITE(DPLL_A, s3_priv->saveDPLL_A &
558 558 ~DPLL_VCO_ENABLE);
559 559 drv_usecwait(150);
560 560 }
561 561 S3_WRITE(FPA0, s3_priv->saveFPA0);
562 562 S3_WRITE(FPA1, s3_priv->saveFPA1);
563 563 /* Actually enable it */
564 564 S3_WRITE(DPLL_A, s3_priv->saveDPLL_A);
565 565 drv_usecwait(150);
566 566 if (IS_I965G(dev))
567 567 S3_WRITE(DPLL_A_MD, s3_priv->saveDPLL_A_MD);
568 568 drv_usecwait(150);
569 569
570 570 /* Restore mode */
571 571 S3_WRITE(HTOTAL_A, s3_priv->saveHTOTAL_A);
572 572 S3_WRITE(HBLANK_A, s3_priv->saveHBLANK_A);
573 573 S3_WRITE(HSYNC_A, s3_priv->saveHSYNC_A);
574 574 S3_WRITE(VTOTAL_A, s3_priv->saveVTOTAL_A);
575 575 S3_WRITE(VBLANK_A, s3_priv->saveVBLANK_A);
576 576 S3_WRITE(VSYNC_A, s3_priv->saveVSYNC_A);
577 577 S3_WRITE(BCLRPAT_A, s3_priv->saveBCLRPAT_A);
578 578
579 579 /* Restore plane info */
580 580 S3_WRITE(DSPASIZE, s3_priv->saveDSPASIZE);
581 581 S3_WRITE(DSPAPOS, s3_priv->saveDSPAPOS);
582 582 S3_WRITE(PIPEASRC, s3_priv->savePIPEASRC);
583 583 S3_WRITE(DSPABASE, s3_priv->saveDSPABASE);
584 584 S3_WRITE(DSPASTRIDE, s3_priv->saveDSPASTRIDE);
585 585 if (IS_I965G(dev)) {
586 586 S3_WRITE(DSPASURF, s3_priv->saveDSPASURF);
587 587 S3_WRITE(DSPATILEOFF, s3_priv->saveDSPATILEOFF);
588 588 }
589 589 S3_WRITE(PIPEACONF, s3_priv->savePIPEACONF);
590 590 i915_restore_palette(dev, PIPE_A);
591 591 /* Enable the plane */
592 592 S3_WRITE(DSPACNTR, s3_priv->saveDSPACNTR);
593 593 S3_WRITE(DSPABASE, S3_READ(DSPABASE));
594 594
595 595 /* Pipe & plane B info */
596 596 if (s3_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
597 597 S3_WRITE(DPLL_B, s3_priv->saveDPLL_B &
598 598 ~DPLL_VCO_ENABLE);
599 599 drv_usecwait(150);
600 600 }
601 601 S3_WRITE(FPB0, s3_priv->saveFPB0);
602 602 S3_WRITE(FPB1, s3_priv->saveFPB1);
603 603 /* Actually enable it */
604 604 S3_WRITE(DPLL_B, s3_priv->saveDPLL_B);
605 605 drv_usecwait(150);
606 606 if (IS_I965G(dev))
607 607 S3_WRITE(DPLL_B_MD, s3_priv->saveDPLL_B_MD);
608 608 drv_usecwait(150);
609 609
610 610 /* Restore mode */
611 611 S3_WRITE(HTOTAL_B, s3_priv->saveHTOTAL_B);
612 612 S3_WRITE(HBLANK_B, s3_priv->saveHBLANK_B);
613 613 S3_WRITE(HSYNC_B, s3_priv->saveHSYNC_B);
614 614 S3_WRITE(VTOTAL_B, s3_priv->saveVTOTAL_B);
615 615 S3_WRITE(VBLANK_B, s3_priv->saveVBLANK_B);
616 616 S3_WRITE(VSYNC_B, s3_priv->saveVSYNC_B);
617 617 S3_WRITE(BCLRPAT_B, s3_priv->saveBCLRPAT_B);
618 618
619 619 /* Restore plane info */
620 620 S3_WRITE(DSPBSIZE, s3_priv->saveDSPBSIZE);
621 621 S3_WRITE(DSPBPOS, s3_priv->saveDSPBPOS);
622 622 S3_WRITE(PIPEBSRC, s3_priv->savePIPEBSRC);
623 623 S3_WRITE(DSPBBASE, s3_priv->saveDSPBBASE);
624 624 S3_WRITE(DSPBSTRIDE, s3_priv->saveDSPBSTRIDE);
625 625 if (IS_I965G(dev)) {
626 626 S3_WRITE(DSPBSURF, s3_priv->saveDSPBSURF);
627 627 S3_WRITE(DSPBTILEOFF, s3_priv->saveDSPBTILEOFF);
628 628 }
629 629 S3_WRITE(PIPEBCONF, s3_priv->savePIPEBCONF);
630 630 i915_restore_palette(dev, PIPE_B);
631 631 /* Enable the plane */
632 632 S3_WRITE(DSPBCNTR, s3_priv->saveDSPBCNTR);
633 633 S3_WRITE(DSPBBASE, S3_READ(DSPBBASE));
634 634
635 635 /* CRT state */
636 636 S3_WRITE(ADPA, s3_priv->saveADPA);
637 637
638 638 /* LVDS state */
639 639 if (IS_I965G(dev))
640 640 S3_WRITE(BLC_PWM_CTL2, s3_priv->saveBLC_PWM_CTL2);
641 641 if (IS_MOBILE(dev) && !IS_I830(dev))
642 642 S3_WRITE(LVDS, s3_priv->saveLVDS);
643 643 if (!IS_I830(dev) && !IS_845G(dev))
644 644 S3_WRITE(PFIT_CONTROL, s3_priv->savePFIT_CONTROL);
645 645
646 646 S3_WRITE(PFIT_PGM_RATIOS, s3_priv->savePFIT_PGM_RATIOS);
647 647 S3_WRITE(BLC_PWM_CTL, s3_priv->saveBLC_PWM_CTL);
648 648 S3_WRITE(LVDSPP_ON, s3_priv->saveLVDSPP_ON);
649 649 S3_WRITE(LVDSPP_OFF, s3_priv->saveLVDSPP_OFF);
650 650 S3_WRITE(PP_CYCLE, s3_priv->savePP_CYCLE);
651 651 S3_WRITE(PP_CONTROL, s3_priv->savePP_CONTROL);
652 652
653 653 /* FIXME: restore TV & SDVO state */
654 654
655 655 /* FBC info */
656 656 S3_WRITE(FBC_CFB_BASE, s3_priv->saveFBC_CFB_BASE);
657 657 S3_WRITE(FBC_LL_BASE, s3_priv->saveFBC_LL_BASE);
658 658 S3_WRITE(FBC_CONTROL2, s3_priv->saveFBC_CONTROL2);
659 659 S3_WRITE(FBC_CONTROL, s3_priv->saveFBC_CONTROL);
660 660
661 661 /* VGA state */
662 662 S3_WRITE(VGACNTRL, s3_priv->saveVGACNTRL);
663 663 S3_WRITE(VCLK_DIVISOR_VGA0, s3_priv->saveVCLK_DIVISOR_VGA0);
664 664 S3_WRITE(VCLK_DIVISOR_VGA1, s3_priv->saveVCLK_DIVISOR_VGA1);
665 665 S3_WRITE(VCLK_POST_DIV, s3_priv->saveVCLK_POST_DIV);
666 666 drv_usecwait(150);
667 667
668 668 i915_restore_vga(dev);
669 669 }
670 670 static int
671 671 i915_resume(struct drm_device *dev)
672 672 {
673 673 ddi_acc_handle_t conf_hdl;
674 674 struct s3_i915_private *s3_priv = dev->s3_private;
675 675 int i;
676 676
677 677 if (pci_config_setup(dev->dip, &conf_hdl) != DDI_SUCCESS) {
678 678 DRM_ERROR(("i915_resume: pci_config_setup fail"));
679 679 return (DDI_FAILURE);
680 680 }
681 681 /*
682 682 * Nexus driver will resume pci config space and set the power state
683 683 * for its children. So we needn't resume them explicitly here.
684 684 * see pci_pre_resume for detail.
685 685 */
686 686 pci_config_put8(conf_hdl, LBB, s3_priv->saveLBB);
687 687
688 688 if (IS_I965G(dev) && IS_MOBILE(dev))
689 689 S3_WRITE(MCHBAR_RENDER_STANDBY, s3_priv->saveRENDERSTANDBY);
690 690 if (IS_I965GM(dev))
691 691 (void) S3_READ(MCHBAR_RENDER_STANDBY);
692 692
693 693 S3_WRITE(HWS_PGA, s3_priv->saveHWS);
694 694 if (IS_I965GM(dev))
695 695 (void) S3_READ(HWS_PGA);
696 696
697 697 i915_restore_display(dev);
698 698
699 699 /* Clock gating state */
700 700 S3_WRITE (D_STATE, s3_priv->saveD_STATE);
701 701 S3_WRITE (CG_2D_DIS, s3_priv->saveCG_2D_DIS);
702 702
703 703 /* Cache mode state */
704 704 S3_WRITE (CACHE_MODE_0, s3_priv->saveCACHE_MODE_0 | 0xffff0000);
705 705
706 706 /* Memory arbitration state */
707 707 S3_WRITE (MI_ARB_STATE, s3_priv->saveMI_ARB_STATE | 0xffff0000);
708 708
709 709 for (i = 0; i < 16; i++) {
710 710 S3_WRITE(SWF0 + (i << 2), s3_priv->saveSWF0[i]);
711 711 S3_WRITE(SWF10 + (i << 2), s3_priv->saveSWF1[i+7]);
712 712 }
713 713 for (i = 0; i < 3; i++)
714 714 S3_WRITE(SWF30 + (i << 2), s3_priv->saveSWF2[i]);
715 715
716 716 S3_WRITE(I915REG_PGTBL_CTRL, s3_priv->pgtbl_ctl);
717 717
718 718 (void) pci_config_teardown(&conf_hdl);
719 719
720 720 drm_agp_rebind(dev);
721 721
722 722 return (DDI_SUCCESS);
723 723 }
724 724
725 725 static int
726 726 i915_suspend(struct drm_device *dev)
727 727 {
728 728 ddi_acc_handle_t conf_hdl;
729 729 struct s3_i915_private *s3_priv = dev->s3_private;
730 730 int i;
731 731
732 732 if (pci_config_setup(dev->dip, &conf_hdl) != DDI_SUCCESS) {
733 733 DRM_ERROR(("i915_suspend: pci_config_setup fail"));
734 734 return (DDI_FAILURE);
735 735 }
736 736
737 737 /*
738 738 * Nexus driver will resume pci config space for its children.
739 739 * So pci config registers are not saved here.
740 740 */
741 741 s3_priv->saveLBB = pci_config_get8(conf_hdl, LBB);
742 742
743 743 if (IS_I965G(dev) && IS_MOBILE(dev))
744 744 s3_priv->saveRENDERSTANDBY = S3_READ(MCHBAR_RENDER_STANDBY);
745 745
746 746 /* Hardware status page */
747 747 s3_priv->saveHWS = S3_READ(HWS_PGA);
748 748
749 749 i915_save_display(dev);
750 750
751 751 /* Interrupt state */
752 752 s3_priv->saveIIR = S3_READ(IIR);
753 753 s3_priv->saveIER = S3_READ(IER);
754 754 s3_priv->saveIMR = S3_READ(IMR);
755 755
756 756 /* Clock gating state */
757 757 s3_priv->saveD_STATE = S3_READ(D_STATE);
758 758 s3_priv->saveCG_2D_DIS = S3_READ(CG_2D_DIS);
759 759
760 760 /* Cache mode state */
761 761 s3_priv->saveCACHE_MODE_0 = S3_READ(CACHE_MODE_0);
762 762
763 763 /* Memory Arbitration state */
764 764 s3_priv->saveMI_ARB_STATE = S3_READ(MI_ARB_STATE);
765 765
766 766 /* Scratch space */
767 767 for (i = 0; i < 16; i++) {
768 768 s3_priv->saveSWF0[i] = S3_READ(SWF0 + (i << 2));
769 769 s3_priv->saveSWF1[i] = S3_READ(SWF10 + (i << 2));
770 770 }
771 771 for (i = 0; i < 3; i++)
772 772 s3_priv->saveSWF2[i] = S3_READ(SWF30 + (i << 2));
773 773
774 774 /*
775 775 * Save page table control register
776 776 */
777 777 s3_priv->pgtbl_ctl = S3_READ(I915REG_PGTBL_CTRL);
778 778
779 779 (void) pci_config_teardown(&conf_hdl);
780 780
781 781 return (DDI_SUCCESS);
782 782 }
783 783
784 784 /*
785 785 * This funtion check the length of memory mapped IO space to get the right bar. * And There are two possibilities here.
786 786 * 1. The MMIO registers is in memory map IO bar with 1M size. The bottom half
787 787 * of the 1M space is the MMIO registers.
788 788 * 2. The MMIO register is in memory map IO with 512K size. The whole 512K
789 789 * space is the MMIO registers.
790 790 */
791 791 static int
792 792 i915_map_regs(dev_info_t *dip, caddr_t *save_addr, ddi_acc_handle_t *handlep)
793 793 {
794 794 int rnumber;
795 795 int nregs;
796 796 off_t size = 0;
797 797
798 798 if (ddi_dev_nregs(dip, &nregs)) {
799 799 cmn_err(CE_WARN, "i915_map_regs: failed to get nregs");
800 800 return (DDI_FAILURE);
801 801 }
802 802
803 803 for (rnumber = 1; rnumber < nregs; rnumber++) {
804 804 (void) ddi_dev_regsize(dip, rnumber, &size);
805 805 if ((size == 0x80000) ||
806 806 (size == 0x100000) ||
807 807 (size == 0x400000))
808 808 break;
809 809 }
810 810
811 811 if (rnumber >= nregs) {
812 812 cmn_err(CE_WARN,
813 813 "i915_map_regs: failed to find MMIO registers");
814 814 return (DDI_FAILURE);
815 815 }
816 816
817 817 if (ddi_regs_map_setup(dip, rnumber, save_addr,
818 818 0, 0x80000, &s3_attr, handlep)) {
819 819 cmn_err(CE_WARN,
820 820 "i915_map_regs: failed to map bar %d", rnumber);
821 821 return (DDI_FAILURE);
822 822 }
823 823
824 824 return (DDI_SUCCESS);
825 825 }
826 826 static void
827 827 i915_unmap_regs(ddi_acc_handle_t *handlep)
828 828 {
829 829 ddi_regs_map_free(handlep);
830 830 }
831 831 static int
832 832 i915_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
833 833 {
834 834 drm_device_t *statep;
835 835 s3_i915_private_t *s3_private;
836 836 void *handle;
837 837 int unit;
838 838
839 839 unit = ddi_get_instance(dip);
840 840 switch (cmd) {
841 841 case DDI_ATTACH:
842 842 break;
843 843 case DDI_RESUME:
844 844 statep = ddi_get_soft_state(i915_statep, unit);
845 845 return (i915_resume(statep));
846 846 default:
847 847 DRM_ERROR("i915_attach: attach and resume ops are supported");
848 848 return (DDI_FAILURE);
849 849
850 850 }
851 851
852 852 if (ddi_soft_state_zalloc(i915_statep, unit) != DDI_SUCCESS) {
853 853 cmn_err(CE_WARN,
854 854 "i915_attach: failed to alloc softstate");
855 855 return (DDI_FAILURE);
856 856 }
857 857 statep = ddi_get_soft_state(i915_statep, unit);
858 858 statep->dip = dip;
859 859 statep->driver = &i915_driver;
860 860
861 861 statep->s3_private = drm_alloc(sizeof(s3_i915_private_t),
862 862 DRM_MEM_DRIVER);
863 863
864 864 if (statep->s3_private == NULL) {
865 865 cmn_err(CE_WARN, "i915_attach: failed to allocate s3 priv");
866 866 goto err_exit1;
867 867 }
868 868
869 869 /*
870 870 * Map in the mmio register space for s3.
871 871 */
872 872 s3_private = (s3_i915_private_t *)statep->s3_private;
873 873
874 874 if (i915_map_regs(dip, &s3_private->saveAddr,
875 875 &s3_private->saveHandle)) {
876 876 cmn_err(CE_WARN, "i915_attach: failed to map MMIO");
877 877 goto err_exit2;
878 878 }
879 879
880 880 /*
881 881 * Call drm_supp_register to create minor nodes for us
882 882 */
883 883 handle = drm_supp_register(dip, statep);
884 884 if ( handle == NULL) {
885 885 DRM_ERROR("i915_attach: drm_supp_register failed");
886 886 goto err_exit3;
887 887 }
888 888 statep->drm_handle = handle;
889 889
890 890 /*
891 891 * After drm_supp_register, we can call drm_xxx routine
892 892 */
893 893 statep->drm_supported = DRM_UNSUPPORT;
894 894 if (
895 895 drm_probe(statep, i915_pciidlist) != DDI_SUCCESS) {
896 896 DRM_ERROR("i915_open: "
897 897 "DRM current don't support this graphics card");
898 898 goto err_exit4;
899 899 }
900 900 statep->drm_supported = DRM_SUPPORT;
901 901
902 902 /* call common attach code */
903 903 if (drm_attach(statep) != DDI_SUCCESS) {
904 904 DRM_ERROR("i915_attach: drm_attach failed");
905 905 goto err_exit4;
906 906 }
907 907 return (DDI_SUCCESS);
908 908 err_exit4:
909 909 (void) drm_supp_unregister(handle);
910 910 err_exit3:
911 911 i915_unmap_regs(&s3_private->saveHandle);
912 912 err_exit2:
913 913 drm_free(statep->s3_private, sizeof(s3_i915_private_t),
914 914 DRM_MEM_DRIVER);
915 915 err_exit1:
916 916 (void) ddi_soft_state_free(i915_statep, unit);
917 917
918 918 return (DDI_FAILURE);
919 919
920 920 } /* i915_attach() */
921 921
922 922 static int
923 923 i915_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
924 924 {
925 925 drm_device_t *statep;
926 926 int unit;
927 927 s3_i915_private_t *s3_private;
928 928
929 929 if ((cmd != DDI_SUSPEND) && (cmd != DDI_DETACH)) {
930 930 DRM_ERROR("i915_detach: "
931 931 "only detach and resume ops are supported");
932 932 return (DDI_FAILURE);
933 933 }
934 934
935 935 unit = ddi_get_instance(dip);
936 936 statep = ddi_get_soft_state(i915_statep, unit);
937 937 if (statep == NULL) {
938 938 DRM_ERROR("i915_detach: can not get soft state");
939 939 return (DDI_FAILURE);
940 940 }
941 941
942 942 if (cmd == DDI_SUSPEND)
943 943 return (i915_suspend(statep));
944 944
945 945 s3_private = (s3_i915_private_t *)statep->s3_private;
946 946 ddi_regs_map_free(&s3_private->saveHandle);
947 947
948 948 /*
949 949 * Free the struct for context saving in S3
950 950 */
951 951 drm_free(statep->s3_private, sizeof(s3_i915_private_t),
952 952 DRM_MEM_DRIVER);
953 953
954 954 (void) drm_detach(statep);
955 955 (void) drm_supp_unregister(statep->drm_handle);
956 956 (void) ddi_soft_state_free(i915_statep, unit);
957 957
958 958 return (DDI_SUCCESS);
959 959
960 960 } /* i915_detach() */
961 961
962 962
963 963 /*ARGSUSED*/
964 964 static int
965 965 i915_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
966 966 {
967 967 drm_device_t *statep;
968 968 int error = DDI_SUCCESS;
969 969 int unit;
970 970
971 971 unit = drm_dev_to_instance((dev_t)arg);
972 972 switch (infocmd) {
973 973 case DDI_INFO_DEVT2DEVINFO:
974 974 statep = ddi_get_soft_state(i915_statep, unit);
975 975 if (statep == NULL || statep->dip == NULL) {
976 976 error = DDI_FAILURE;
977 977 } else {
978 978 *result = (void *) statep->dip;
979 979 error = DDI_SUCCESS;
980 980 }
981 981 break;
982 982 case DDI_INFO_DEVT2INSTANCE:
983 983 *result = (void *)(uintptr_t)unit;
984 984 error = DDI_SUCCESS;
985 985 break;
986 986 default:
987 987 error = DDI_FAILURE;
988 988 break;
989 989 }
990 990 return (error);
991 991
992 992 } /* i915_info() */
993 993
994 994
995 995 static void i915_configure(drm_driver_t *driver)
996 996 {
997 997 driver->buf_priv_size = 1; /* No dev_priv */
998 998 driver->load = i915_driver_load;
999 999 driver->unload = i915_driver_unload;
1000 1000 driver->open = i915_driver_open;
1001 1001 driver->preclose = i915_driver_preclose;
1002 1002 driver->postclose = i915_driver_postclose;
1003 1003 driver->lastclose = i915_driver_lastclose;
1004 1004 driver->device_is_agp = i915_driver_device_is_agp;
1005 1005 driver->enable_vblank = i915_enable_vblank;
1006 1006 driver->disable_vblank = i915_disable_vblank;
1007 1007 driver->irq_preinstall = i915_driver_irq_preinstall;
1008 1008 driver->irq_postinstall = i915_driver_irq_postinstall;
1009 1009 driver->irq_uninstall = i915_driver_irq_uninstall;
1010 1010 driver->irq_handler = i915_driver_irq_handler;
1011 1011
1012 1012 driver->gem_init_object = i915_gem_init_object;
1013 1013 driver->gem_free_object = i915_gem_free_object;
1014 1014
1015 1015 driver->driver_ioctls = i915_ioctls;
1016 1016 driver->max_driver_ioctl = i915_max_ioctl;
1017 1017
1018 1018 driver->driver_name = DRIVER_NAME;
1019 1019 driver->driver_desc = DRIVER_DESC;
1020 1020 driver->driver_date = DRIVER_DATE;
1021 1021 driver->driver_major = DRIVER_MAJOR;
1022 1022 driver->driver_minor = DRIVER_MINOR;
1023 1023 driver->driver_patchlevel = DRIVER_PATCHLEVEL;
1024 1024
1025 1025 driver->use_agp = 1;
1026 1026 driver->require_agp = 1;
1027 1027 driver->use_irq = 1;
1028 1028 }
1029 1029
1030 1030 static int i915_quiesce(dev_info_t *dip)
1031 1031 {
1032 1032 drm_device_t *statep;
1033 1033 int unit;
1034 1034
1035 1035 unit = ddi_get_instance(dip);
1036 1036 statep = ddi_get_soft_state(i915_statep, unit);
1037 1037 if (statep == NULL) {
1038 1038 return (DDI_FAILURE);
1039 1039 }
1040 1040 i915_driver_irq_uninstall(statep);
1041 1041
1042 1042 return (DDI_SUCCESS);
1043 1043 }
↓ open down ↓ |
906 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX