agp_i810.c revision 1.73.4.1 1 /* $NetBSD: agp_i810.c,v 1.73.4.1 2014/05/22 11:40:24 yamt Exp $ */
2
3 /*-
4 * Copyright (c) 2000 Doug Rabson
5 * Copyright (c) 2000 Ruslan Ermilov
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD$
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.73.4.1 2014/05/22 11:40:24 yamt Exp $");
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>
38 #include <sys/kernel.h>
39 #include <sys/proc.h>
40 #include <sys/device.h>
41 #include <sys/conf.h>
42
43 #include <dev/pci/pcivar.h>
44 #include <dev/pci/pcireg.h>
45 #include <dev/pci/pcidevs.h>
46 #include <dev/pci/agpvar.h>
47 #include <dev/pci/agpreg.h>
48 #include <dev/pci/agp_i810var.h>
49
50 #include <sys/agpio.h>
51
52 #include <sys/bus.h>
53
54 #include "agp_intel.h"
55
56 struct agp_softc *agp_i810_sc = NULL;
57
58 #define READ1(off) bus_space_read_1(isc->bst, isc->bsh, off)
59 #define READ4(off) bus_space_read_4(isc->bst, isc->bsh, off)
60 #define WRITE4(off,v) bus_space_write_4(isc->bst, isc->bsh, off, v)
61
62 #define CHIP_I810 0 /* i810/i815 */
63 #define CHIP_I830 1 /* 830M/845G */
64 #define CHIP_I855 2 /* 852GM/855GM/865G */
65 #define CHIP_I915 3 /* 915G/915GM/945G/945GM/945GME */
66 #define CHIP_I965 4 /* 965Q/965PM */
67 #define CHIP_G33 5 /* G33/Q33/Q35 */
68 #define CHIP_G4X 6 /* G45/Q45 */
69
70 /* XXX hack, see below */
71 static bus_addr_t agp_i810_vga_regbase;
72 static bus_space_handle_t agp_i810_vga_bsh;
73
74 static u_int32_t agp_i810_get_aperture(struct agp_softc *);
75 static int agp_i810_set_aperture(struct agp_softc *, u_int32_t);
76 static int agp_i810_bind_page(struct agp_softc *, off_t, bus_addr_t);
77 static int agp_i810_unbind_page(struct agp_softc *, off_t);
78 static void agp_i810_flush_tlb(struct agp_softc *);
79 static int agp_i810_enable(struct agp_softc *, u_int32_t mode);
80 static struct agp_memory *agp_i810_alloc_memory(struct agp_softc *, int,
81 vsize_t);
82 static int agp_i810_free_memory(struct agp_softc *, struct agp_memory *);
83 static int agp_i810_bind_memory(struct agp_softc *, struct agp_memory *, off_t);
84 static int agp_i810_unbind_memory(struct agp_softc *, struct agp_memory *);
85
86 static bool agp_i810_resume(device_t, const pmf_qual_t *);
87 static int agp_i810_init(struct agp_softc *);
88
89 static int agp_i810_init(struct agp_softc *);
90
91 static struct agp_methods agp_i810_methods = {
92 agp_i810_get_aperture,
93 agp_i810_set_aperture,
94 agp_i810_bind_page,
95 agp_i810_unbind_page,
96 agp_i810_flush_tlb,
97 agp_i810_enable,
98 agp_i810_alloc_memory,
99 agp_i810_free_memory,
100 agp_i810_bind_memory,
101 agp_i810_unbind_memory,
102 };
103
104 int
105 agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, bus_addr_t v)
106 {
107 u_int32_t pte;
108 bus_size_t base_off, wroff;
109
110 /* Bits 11:4 (physical start address extension) should be zero. */
111 if ((v & 0xff0) != 0)
112 return EINVAL;
113
114 pte = (u_int32_t)v;
115 /*
116 * We need to massage the pte if bus_addr_t is wider than 32 bits.
117 * The compiler isn't smart enough, hence the casts to uintmax_t.
118 */
119 if (sizeof(bus_addr_t) > sizeof(u_int32_t)) {
120 /* 965+ can do 36-bit addressing, add in the extra bits. */
121 if (isc->chiptype == CHIP_I965 ||
122 isc->chiptype == CHIP_G33 ||
123 isc->chiptype == CHIP_G4X) {
124 if (((uintmax_t)v >> 36) != 0)
125 return EINVAL;
126 pte |= (v >> 28) & 0xf0;
127 } else {
128 if (((uintmax_t)v >> 32) != 0)
129 return EINVAL;
130 }
131 }
132
133 base_off = 0;
134 wroff = (off >> AGP_PAGE_SHIFT) * 4;
135
136 switch (isc->chiptype) {
137 case CHIP_I810:
138 case CHIP_I830:
139 case CHIP_I855:
140 base_off = AGP_I810_GTT;
141 break;
142 case CHIP_I965:
143 base_off = AGP_I965_GTT;
144 break;
145 case CHIP_G4X:
146 base_off = AGP_G4X_GTT;
147 break;
148 case CHIP_I915:
149 case CHIP_G33:
150 bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, wroff, pte);
151 return 0;
152 }
153
154 WRITE4(base_off + wroff, pte);
155 return 0;
156 }
157
158 void
159 agp_i810_post_gtt_entry(struct agp_i810_softc *isc, off_t off)
160 {
161 bus_size_t base_off, wroff;
162
163 base_off = 0;
164 wroff = (off >> AGP_PAGE_SHIFT) * 4;
165
166 switch (isc->chiptype) {
167 case CHIP_I810:
168 case CHIP_I830:
169 case CHIP_I855:
170 base_off = AGP_I810_GTT;
171 break;
172 case CHIP_I965:
173 base_off = AGP_I965_GTT;
174 break;
175 case CHIP_G4X:
176 base_off = AGP_G4X_GTT;
177 break;
178 case CHIP_I915:
179 case CHIP_G33:
180 (void)bus_space_read_4(isc->gtt_bst, isc->gtt_bsh, wroff);
181 return;
182 }
183
184 (void)READ4(base_off + wroff);
185 }
186
187 /* XXXthorpej -- duplicated code (see arch/x86/pci/pchb.c) */
188 static int
189 agp_i810_vgamatch(const struct pci_attach_args *pa)
190 {
191
192 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
193 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
194 return (0);
195
196 switch (PCI_PRODUCT(pa->pa_id)) {
197 case PCI_PRODUCT_INTEL_82810_GC:
198 case PCI_PRODUCT_INTEL_82810_DC100_GC:
199 case PCI_PRODUCT_INTEL_82810E_GC:
200 case PCI_PRODUCT_INTEL_82815_FULL_GRAPH:
201 case PCI_PRODUCT_INTEL_82830MP_IV:
202 case PCI_PRODUCT_INTEL_82845G_IGD:
203 case PCI_PRODUCT_INTEL_82855GM_IGD:
204 case PCI_PRODUCT_INTEL_82865_IGD:
205 case PCI_PRODUCT_INTEL_82915G_IGD:
206 case PCI_PRODUCT_INTEL_82915GM_IGD:
207 case PCI_PRODUCT_INTEL_82945P_IGD:
208 case PCI_PRODUCT_INTEL_82945GM_IGD:
209 case PCI_PRODUCT_INTEL_82945GM_IGD_1:
210 case PCI_PRODUCT_INTEL_82945GME_IGD:
211 case PCI_PRODUCT_INTEL_E7221_IGD:
212 case PCI_PRODUCT_INTEL_82965Q_IGD:
213 case PCI_PRODUCT_INTEL_82965Q_IGD_1:
214 case PCI_PRODUCT_INTEL_82965PM_IGD:
215 case PCI_PRODUCT_INTEL_82965PM_IGD_1:
216 case PCI_PRODUCT_INTEL_82G33_IGD:
217 case PCI_PRODUCT_INTEL_82G33_IGD_1:
218 case PCI_PRODUCT_INTEL_82965G_IGD:
219 case PCI_PRODUCT_INTEL_82965G_IGD_1:
220 case PCI_PRODUCT_INTEL_82965GME_IGD:
221 case PCI_PRODUCT_INTEL_82Q35_IGD:
222 case PCI_PRODUCT_INTEL_82Q35_IGD_1:
223 case PCI_PRODUCT_INTEL_82Q33_IGD:
224 case PCI_PRODUCT_INTEL_82Q33_IGD_1:
225 case PCI_PRODUCT_INTEL_82G35_IGD:
226 case PCI_PRODUCT_INTEL_82G35_IGD_1:
227 case PCI_PRODUCT_INTEL_82946GZ_IGD:
228 case PCI_PRODUCT_INTEL_82GM45_IGD:
229 case PCI_PRODUCT_INTEL_82GM45_IGD_1:
230 case PCI_PRODUCT_INTEL_82IGD_E_IGD:
231 case PCI_PRODUCT_INTEL_82Q45_IGD:
232 case PCI_PRODUCT_INTEL_82G45_IGD:
233 case PCI_PRODUCT_INTEL_82G41_IGD:
234 case PCI_PRODUCT_INTEL_82B43_IGD:
235 case PCI_PRODUCT_INTEL_IRONLAKE_D_IGD:
236 case PCI_PRODUCT_INTEL_IRONLAKE_M_IGD:
237 case PCI_PRODUCT_INTEL_PINEVIEW_IGD:
238 case PCI_PRODUCT_INTEL_PINEVIEW_M_IGD:
239 return (1);
240 }
241
242 return (0);
243 }
244
245 static int
246 agp_i965_map_aperture(struct pci_attach_args *pa, struct agp_softc *sc, int reg)
247 {
248 /*
249 * Find the aperture. Don't map it (yet), this would
250 * eat KVA.
251 */
252 if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, reg,
253 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_64BIT, &sc->as_apaddr, &sc->as_apsize,
254 &sc->as_apflags) != 0)
255 return ENXIO;
256
257 sc->as_apt = pa->pa_memt;
258
259 return 0;
260 }
261
262 int
263 agp_i810_attach(device_t parent, device_t self, void *aux)
264 {
265 struct agp_softc *sc = device_private(self);
266 struct agp_i810_softc *isc;
267 struct agp_gatt *gatt;
268 int error, apbase;
269 bus_addr_t mmadr;
270 bus_size_t mmadrsize;
271
272 isc = malloc(sizeof *isc, M_AGP, M_NOWAIT|M_ZERO);
273 if (isc == NULL) {
274 aprint_error(": can't allocate chipset-specific softc\n");
275 return ENOMEM;
276 }
277 sc->as_chipc = isc;
278 sc->as_methods = &agp_i810_methods;
279
280 if (pci_find_device(&isc->vga_pa, agp_i810_vgamatch) == 0) {
281 #if NAGP_INTEL > 0
282 const struct pci_attach_args *pa = aux;
283
284 switch (PCI_PRODUCT(pa->pa_id)) {
285 case PCI_PRODUCT_INTEL_82840_HB:
286 case PCI_PRODUCT_INTEL_82865_HB:
287 case PCI_PRODUCT_INTEL_82845G_DRAM:
288 case PCI_PRODUCT_INTEL_82815_FULL_HUB:
289 case PCI_PRODUCT_INTEL_82855GM_MCH:
290 return agp_intel_attach(parent, self, aux);
291 }
292 #endif
293 aprint_error(": can't find internal VGA device config space\n");
294 free(isc, M_AGP);
295 return ENOENT;
296 }
297
298 /* XXXfvdl */
299 sc->as_dmat = isc->vga_pa.pa_dmat;
300
301 switch (PCI_PRODUCT(isc->vga_pa.pa_id)) {
302 case PCI_PRODUCT_INTEL_82810_GC:
303 case PCI_PRODUCT_INTEL_82810_DC100_GC:
304 case PCI_PRODUCT_INTEL_82810E_GC:
305 case PCI_PRODUCT_INTEL_82815_FULL_GRAPH:
306 isc->chiptype = CHIP_I810;
307 break;
308 case PCI_PRODUCT_INTEL_82830MP_IV:
309 case PCI_PRODUCT_INTEL_82845G_IGD:
310 isc->chiptype = CHIP_I830;
311 break;
312 case PCI_PRODUCT_INTEL_82855GM_IGD:
313 case PCI_PRODUCT_INTEL_82865_IGD:
314 isc->chiptype = CHIP_I855;
315 break;
316 case PCI_PRODUCT_INTEL_82915G_IGD:
317 case PCI_PRODUCT_INTEL_82915GM_IGD:
318 case PCI_PRODUCT_INTEL_82945P_IGD:
319 case PCI_PRODUCT_INTEL_82945GM_IGD:
320 case PCI_PRODUCT_INTEL_82945GM_IGD_1:
321 case PCI_PRODUCT_INTEL_82945GME_IGD:
322 case PCI_PRODUCT_INTEL_E7221_IGD:
323 case PCI_PRODUCT_INTEL_PINEVIEW_IGD:
324 case PCI_PRODUCT_INTEL_PINEVIEW_M_IGD:
325 isc->chiptype = CHIP_I915;
326 break;
327 case PCI_PRODUCT_INTEL_82965Q_IGD:
328 case PCI_PRODUCT_INTEL_82965Q_IGD_1:
329 case PCI_PRODUCT_INTEL_82965PM_IGD:
330 case PCI_PRODUCT_INTEL_82965PM_IGD_1:
331 case PCI_PRODUCT_INTEL_82965G_IGD:
332 case PCI_PRODUCT_INTEL_82965G_IGD_1:
333 case PCI_PRODUCT_INTEL_82965GME_IGD:
334 case PCI_PRODUCT_INTEL_82946GZ_IGD:
335 case PCI_PRODUCT_INTEL_82G35_IGD:
336 case PCI_PRODUCT_INTEL_82G35_IGD_1:
337 isc->chiptype = CHIP_I965;
338 break;
339 case PCI_PRODUCT_INTEL_82Q35_IGD:
340 case PCI_PRODUCT_INTEL_82Q35_IGD_1:
341 case PCI_PRODUCT_INTEL_82G33_IGD:
342 case PCI_PRODUCT_INTEL_82G33_IGD_1:
343 case PCI_PRODUCT_INTEL_82Q33_IGD:
344 case PCI_PRODUCT_INTEL_82Q33_IGD_1:
345 isc->chiptype = CHIP_G33;
346 break;
347 case PCI_PRODUCT_INTEL_82GM45_IGD:
348 case PCI_PRODUCT_INTEL_82GM45_IGD_1:
349 case PCI_PRODUCT_INTEL_82IGD_E_IGD:
350 case PCI_PRODUCT_INTEL_82Q45_IGD:
351 case PCI_PRODUCT_INTEL_82G45_IGD:
352 case PCI_PRODUCT_INTEL_82G41_IGD:
353 case PCI_PRODUCT_INTEL_82B43_IGD:
354 case PCI_PRODUCT_INTEL_IRONLAKE_D_IGD:
355 case PCI_PRODUCT_INTEL_IRONLAKE_M_IGD:
356 isc->chiptype = CHIP_G4X;
357 break;
358 }
359
360 switch (isc->chiptype) {
361 case CHIP_I915:
362 case CHIP_G33:
363 apbase = AGP_I915_GMADR;
364 break;
365 case CHIP_I965:
366 case CHIP_G4X:
367 apbase = AGP_I965_GMADR;
368 break;
369 default:
370 apbase = AGP_I810_GMADR;
371 break;
372 }
373
374 if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) {
375 error = agp_i965_map_aperture(&isc->vga_pa, sc, apbase);
376 } else {
377 error = agp_map_aperture(&isc->vga_pa, sc, apbase);
378 }
379 if (error != 0) {
380 aprint_error(": can't map aperture\n");
381 free(isc, M_AGP);
382 return error;
383 }
384
385 if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) {
386 error = pci_mapreg_map(&isc->vga_pa, AGP_I915_MMADR,
387 PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh,
388 &mmadr, &mmadrsize);
389 if (error != 0) {
390 aprint_error(": can't map mmadr registers\n");
391 agp_generic_detach(sc);
392 return error;
393 }
394 error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR,
395 PCI_MAPREG_TYPE_MEM, 0, &isc->gtt_bst, &isc->gtt_bsh,
396 NULL, NULL);
397 if (error != 0) {
398 aprint_error(": can't map gttadr registers\n");
399 /* XXX we should release mmadr here */
400 agp_generic_detach(sc);
401 return error;
402 }
403 } else if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) {
404 error = pci_mapreg_map(&isc->vga_pa, AGP_I965_MMADR,
405 PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh,
406 &mmadr, &mmadrsize);
407 if (error != 0) {
408 aprint_error(": can't map mmadr registers\n");
409 agp_generic_detach(sc);
410 return error;
411 }
412 } else {
413 error = pci_mapreg_map(&isc->vga_pa, AGP_I810_MMADR,
414 PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh,
415 &mmadr, &mmadrsize);
416 if (error != 0) {
417 aprint_error(": can't map mmadr registers\n");
418 agp_generic_detach(sc);
419 return error;
420 }
421 }
422
423 isc->initial_aperture = AGP_GET_APERTURE(sc);
424
425 gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
426 if (!gatt) {
427 agp_generic_detach(sc);
428 return ENOMEM;
429 }
430 isc->gatt = gatt;
431
432 gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT;
433
434 if (!pmf_device_register(self, NULL, agp_i810_resume))
435 aprint_error_dev(self, "couldn't establish power handler\n");
436
437 /*
438 * XXX horrible hack to allow drm code to use our mapping
439 * of VGA chip registers
440 */
441 agp_i810_vga_regbase = mmadr;
442 agp_i810_vga_bsh = isc->bsh;
443
444 return agp_i810_init(sc);
445 }
446
447 /*
448 * XXX horrible hack to allow drm code to use our mapping
449 * of VGA chip registers
450 */
451 int
452 agp_i810_borrow(bus_addr_t base, bus_space_handle_t *hdlp)
453 {
454
455 if (!agp_i810_vga_regbase || base != agp_i810_vga_regbase)
456 return 0;
457 *hdlp = agp_i810_vga_bsh;
458 return 1;
459 }
460
461 static int agp_i810_init(struct agp_softc *sc)
462 {
463 struct agp_i810_softc *isc;
464 struct agp_gatt *gatt;
465
466 isc = sc->as_chipc;
467 gatt = isc->gatt;
468
469 if (isc->chiptype == CHIP_I810) {
470 void *virtual;
471 int dummyseg;
472
473 /* Some i810s have on-chip memory called dcache */
474 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
475 isc->dcache_size = 4 * 1024 * 1024;
476 else
477 isc->dcache_size = 0;
478
479 /* According to the specs the gatt on the i810 must be 64k */
480 if (agp_alloc_dmamem(sc->as_dmat, 64 * 1024,
481 0, &gatt->ag_dmamap, &virtual, &gatt->ag_physical,
482 &gatt->ag_dmaseg, 1, &dummyseg) != 0) {
483 free(gatt, M_AGP);
484 agp_generic_detach(sc);
485 return ENOMEM;
486 }
487 gatt->ag_virtual = (uint32_t *)virtual;
488 gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t);
489 memset(gatt->ag_virtual, 0, gatt->ag_size);
490
491 agp_flush_cache();
492 /* Install the GATT. */
493 WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1);
494 } else if (isc->chiptype == CHIP_I830) {
495 /* The i830 automatically initializes the 128k gatt on boot. */
496 pcireg_t reg;
497 u_int32_t pgtblctl;
498 u_int16_t gcc1;
499
500 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0);
501 gcc1 = (u_int16_t)(reg >> 16);
502 switch (gcc1 & AGP_I830_GCC1_GMS) {
503 case AGP_I830_GCC1_GMS_STOLEN_512:
504 isc->stolen = (512 - 132) * 1024 / 4096;
505 break;
506 case AGP_I830_GCC1_GMS_STOLEN_1024:
507 isc->stolen = (1024 - 132) * 1024 / 4096;
508 break;
509 case AGP_I830_GCC1_GMS_STOLEN_8192:
510 isc->stolen = (8192 - 132) * 1024 / 4096;
511 break;
512 default:
513 isc->stolen = 0;
514 aprint_error(
515 ": unknown memory configuration, disabling\n");
516 agp_generic_detach(sc);
517 return EINVAL;
518 }
519
520 if (isc->stolen > 0) {
521 aprint_normal(": detected %dk stolen memory\n%s",
522 isc->stolen * 4, device_xname(sc->as_dev));
523 }
524
525 /* GATT address is already in there, make sure it's enabled */
526 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
527 pgtblctl |= 1;
528 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
529
530 gatt->ag_physical = pgtblctl & ~1;
531 } else if (isc->chiptype == CHIP_I855 || isc->chiptype == CHIP_I915 ||
532 isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G33 ||
533 isc->chiptype == CHIP_G4X) {
534 pcireg_t reg;
535 u_int32_t pgtblctl, gtt_size, stolen;
536 u_int16_t gcc1;
537
538 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I855_GCC1);
539 gcc1 = (u_int16_t)(reg >> 16);
540
541 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
542
543 /* Stolen memory is set up at the beginning of the aperture by
544 * the BIOS, consisting of the GATT followed by 4kb for the
545 * BIOS display.
546 */
547 switch (isc->chiptype) {
548 case CHIP_I855:
549 gtt_size = 128;
550 break;
551 case CHIP_I915:
552 gtt_size = 256;
553 break;
554 case CHIP_I965:
555 switch (pgtblctl & AGP_I810_PGTBL_SIZE_MASK) {
556 case AGP_I810_PGTBL_SIZE_128KB:
557 case AGP_I810_PGTBL_SIZE_512KB:
558 gtt_size = 512;
559 break;
560 case AGP_I965_PGTBL_SIZE_1MB:
561 gtt_size = 1024;
562 break;
563 case AGP_I965_PGTBL_SIZE_2MB:
564 gtt_size = 2048;
565 break;
566 case AGP_I965_PGTBL_SIZE_1_5MB:
567 gtt_size = 1024 + 512;
568 break;
569 default:
570 aprint_error("Bad PGTBL size\n");
571 agp_generic_detach(sc);
572 return EINVAL;
573 }
574 break;
575 case CHIP_G33:
576 switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK) {
577 case AGP_G33_PGTBL_SIZE_1M:
578 gtt_size = 1024;
579 break;
580 case AGP_G33_PGTBL_SIZE_2M:
581 gtt_size = 2048;
582 break;
583 default:
584 aprint_error(": Bad PGTBL size\n");
585 agp_generic_detach(sc);
586 return EINVAL;
587 }
588 break;
589 case CHIP_G4X:
590 gtt_size = 0;
591 break;
592 default:
593 aprint_error(": bad chiptype\n");
594 agp_generic_detach(sc);
595 return EINVAL;
596 }
597
598 switch (gcc1 & AGP_I855_GCC1_GMS) {
599 case AGP_I855_GCC1_GMS_STOLEN_1M:
600 stolen = 1024;
601 break;
602 case AGP_I855_GCC1_GMS_STOLEN_4M:
603 stolen = 4 * 1024;
604 break;
605 case AGP_I855_GCC1_GMS_STOLEN_8M:
606 stolen = 8 * 1024;
607 break;
608 case AGP_I855_GCC1_GMS_STOLEN_16M:
609 stolen = 16 * 1024;
610 break;
611 case AGP_I855_GCC1_GMS_STOLEN_32M:
612 stolen = 32 * 1024;
613 break;
614 case AGP_I915_GCC1_GMS_STOLEN_48M:
615 stolen = 48 * 1024;
616 break;
617 case AGP_I915_GCC1_GMS_STOLEN_64M:
618 stolen = 64 * 1024;
619 break;
620 case AGP_G33_GCC1_GMS_STOLEN_128M:
621 stolen = 128 * 1024;
622 break;
623 case AGP_G33_GCC1_GMS_STOLEN_256M:
624 stolen = 256 * 1024;
625 break;
626 case AGP_G4X_GCC1_GMS_STOLEN_96M:
627 stolen = 96 * 1024;
628 break;
629 case AGP_G4X_GCC1_GMS_STOLEN_160M:
630 stolen = 160 * 1024;
631 break;
632 case AGP_G4X_GCC1_GMS_STOLEN_224M:
633 stolen = 224 * 1024;
634 break;
635 case AGP_G4X_GCC1_GMS_STOLEN_352M:
636 stolen = 352 * 1024;
637 break;
638 default:
639 aprint_error(
640 ": unknown memory configuration, disabling\n");
641 agp_generic_detach(sc);
642 return EINVAL;
643 }
644
645 switch (gcc1 & AGP_I855_GCC1_GMS) {
646 case AGP_I915_GCC1_GMS_STOLEN_48M:
647 case AGP_I915_GCC1_GMS_STOLEN_64M:
648 if (isc->chiptype != CHIP_I915 &&
649 isc->chiptype != CHIP_I965 &&
650 isc->chiptype != CHIP_G33 &&
651 isc->chiptype != CHIP_G4X)
652 stolen = 0;
653 break;
654 case AGP_G33_GCC1_GMS_STOLEN_128M:
655 case AGP_G33_GCC1_GMS_STOLEN_256M:
656 if (isc->chiptype != CHIP_I965 &&
657 isc->chiptype != CHIP_G33 &&
658 isc->chiptype != CHIP_G4X)
659 stolen = 0;
660 break;
661 case AGP_G4X_GCC1_GMS_STOLEN_96M:
662 case AGP_G4X_GCC1_GMS_STOLEN_160M:
663 case AGP_G4X_GCC1_GMS_STOLEN_224M:
664 case AGP_G4X_GCC1_GMS_STOLEN_352M:
665 if (isc->chiptype != CHIP_I965 &&
666 isc->chiptype != CHIP_G4X)
667 stolen = 0;
668 break;
669 }
670
671 /* BIOS space */
672 gtt_size += 4;
673
674 isc->stolen = (stolen - gtt_size) * 1024 / 4096;
675
676 if (isc->stolen > 0) {
677 aprint_normal(": detected %dk stolen memory\n%s",
678 isc->stolen * 4, device_xname(sc->as_dev));
679 }
680
681 /* GATT address is already in there, make sure it's enabled */
682 pgtblctl |= 1;
683 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
684
685 gatt->ag_physical = pgtblctl & ~1;
686 }
687
688 /*
689 * Make sure the chipset can see everything.
690 */
691 agp_flush_cache();
692
693 /*
694 * Publish what we found for kludgey drivers (I'm looking at
695 * you, drm).
696 */
697 if (agp_i810_sc == NULL)
698 agp_i810_sc = sc;
699 else
700 aprint_error_dev(sc->as_dev, "i810 agp already attached\n");
701
702 return 0;
703 }
704
705 #if 0
706 static int
707 agp_i810_detach(struct agp_softc *sc)
708 {
709 int error;
710 struct agp_i810_softc *isc = sc->as_chipc;
711
712 error = agp_generic_detach(sc);
713 if (error)
714 return error;
715
716 /* Clear the GATT base. */
717 if (sc->chiptype == CHIP_I810) {
718 WRITE4(AGP_I810_PGTBL_CTL, 0);
719 } else {
720 unsigned int pgtblctl;
721 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
722 pgtblctl &= ~1;
723 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
724 }
725
726 /* Put the aperture back the way it started. */
727 AGP_SET_APERTURE(sc, isc->initial_aperture);
728
729 if (sc->chiptype == CHIP_I810) {
730 agp_free_dmamem(sc->as_dmat, gatt->ag_size, gatt->ag_dmamap,
731 (void *)gatt->ag_virtual, &gatt->ag_dmaseg, 1);
732 }
733 free(sc->gatt, M_AGP);
734
735 return 0;
736 }
737 #endif
738
739 static u_int32_t
740 agp_i810_get_aperture(struct agp_softc *sc)
741 {
742 struct agp_i810_softc *isc = sc->as_chipc;
743 pcireg_t reg;
744 u_int32_t size;
745 u_int16_t miscc, gcc1, msac;
746
747 size = 0;
748
749 switch (isc->chiptype) {
750 case CHIP_I810:
751 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM);
752 miscc = (u_int16_t)(reg >> 16);
753 if ((miscc & AGP_I810_MISCC_WINSIZE) ==
754 AGP_I810_MISCC_WINSIZE_32)
755 size = 32 * 1024 * 1024;
756 else
757 size = 64 * 1024 * 1024;
758 break;
759 case CHIP_I830:
760 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0);
761 gcc1 = (u_int16_t)(reg >> 16);
762 if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
763 size = 64 * 1024 * 1024;
764 else
765 size = 128 * 1024 * 1024;
766 break;
767 case CHIP_I855:
768 size = 128 * 1024 * 1024;
769 break;
770 case CHIP_I915:
771 case CHIP_G33:
772 case CHIP_G4X:
773 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I915_MSAC);
774 msac = (u_int16_t)(reg >> 16);
775 if (msac & AGP_I915_MSAC_APER_128M)
776 size = 128 * 1024 * 1024;
777 else
778 size = 256 * 1024 * 1024;
779 break;
780 case CHIP_I965:
781 size = 512 * 1024 * 1024;
782 break;
783 default:
784 aprint_error(": Unknown chipset\n");
785 }
786
787 return size;
788 }
789
790 static int
791 agp_i810_set_aperture(struct agp_softc *sc, u_int32_t aperture)
792 {
793 struct agp_i810_softc *isc = sc->as_chipc;
794 pcireg_t reg;
795 u_int16_t miscc, gcc1;
796
797 switch (isc->chiptype) {
798 case CHIP_I810:
799 /*
800 * Double check for sanity.
801 */
802 if (aperture != (32 * 1024 * 1024) &&
803 aperture != (64 * 1024 * 1024)) {
804 aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
805 aperture);
806 return EINVAL;
807 }
808
809 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM);
810 miscc = (u_int16_t)(reg >> 16);
811 miscc &= ~AGP_I810_MISCC_WINSIZE;
812 if (aperture == 32 * 1024 * 1024)
813 miscc |= AGP_I810_MISCC_WINSIZE_32;
814 else
815 miscc |= AGP_I810_MISCC_WINSIZE_64;
816
817 reg &= 0x0000ffff;
818 reg |= ((pcireg_t)miscc) << 16;
819 pci_conf_write(sc->as_pc, sc->as_tag, AGP_I810_SMRAM, reg);
820 break;
821 case CHIP_I830:
822 if (aperture != (64 * 1024 * 1024) &&
823 aperture != (128 * 1024 * 1024)) {
824 aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
825 aperture);
826 return EINVAL;
827 }
828 reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0);
829 gcc1 = (u_int16_t)(reg >> 16);
830 gcc1 &= ~AGP_I830_GCC1_GMASIZE;
831 if (aperture == 64 * 1024 * 1024)
832 gcc1 |= AGP_I830_GCC1_GMASIZE_64;
833 else
834 gcc1 |= AGP_I830_GCC1_GMASIZE_128;
835
836 reg &= 0x0000ffff;
837 reg |= ((pcireg_t)gcc1) << 16;
838 pci_conf_write(sc->as_pc, sc->as_tag, AGP_I830_GCC0, reg);
839 break;
840 case CHIP_I855:
841 case CHIP_I915:
842 if (aperture != agp_i810_get_aperture(sc)) {
843 aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
844 aperture);
845 return EINVAL;
846 }
847 break;
848 case CHIP_I965:
849 if (aperture != 512 * 1024 * 1024) {
850 aprint_error_dev(sc->as_dev, "bad aperture size %d\n",
851 aperture);
852 return EINVAL;
853 }
854 break;
855 }
856
857 return 0;
858 }
859
860 static int
861 agp_i810_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical)
862 {
863 struct agp_i810_softc *isc = sc->as_chipc;
864
865 if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
866 #ifdef AGP_DEBUG
867 printf("%s: failed: offset 0x%08x, shift %d, entries %d\n",
868 device_xname(sc->as_dev), (int)offset, AGP_PAGE_SHIFT,
869 isc->gatt->ag_entries);
870 #endif
871 return EINVAL;
872 }
873
874 if (isc->chiptype != CHIP_I810) {
875 if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) {
876 #ifdef AGP_DEBUG
877 printf("%s: trying to bind into stolen memory\n",
878 device_xname(sc->as_dev));
879 #endif
880 return EINVAL;
881 }
882 }
883
884 return agp_i810_write_gtt_entry(isc, offset, physical | 1);
885 }
886
887 static int
888 agp_i810_unbind_page(struct agp_softc *sc, off_t offset)
889 {
890 struct agp_i810_softc *isc = sc->as_chipc;
891
892 if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT))
893 return EINVAL;
894
895 if (isc->chiptype != CHIP_I810 ) {
896 if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) {
897 #ifdef AGP_DEBUG
898 printf("%s: trying to unbind from stolen memory\n",
899 device_xname(sc->as_dev));
900 #endif
901 return EINVAL;
902 }
903 }
904
905 return agp_i810_write_gtt_entry(isc, offset, 0);
906 }
907
908 /*
909 * Writing via memory mapped registers already flushes all TLBs.
910 */
911 static void
912 agp_i810_flush_tlb(struct agp_softc *sc)
913 {
914 }
915
916 static int
917 agp_i810_enable(struct agp_softc *sc, u_int32_t mode)
918 {
919
920 return 0;
921 }
922
923 static struct agp_memory *
924 agp_i810_alloc_memory(struct agp_softc *sc, int type, vsize_t size)
925 {
926 struct agp_i810_softc *isc = sc->as_chipc;
927 struct agp_memory *mem;
928
929 #ifdef AGP_DEBUG
930 printf("AGP: alloc(%d, 0x%x)\n", type, (int) size);
931 #endif
932
933 if ((size & (AGP_PAGE_SIZE - 1)) != 0)
934 return 0;
935
936 if (sc->as_allocated + size > sc->as_maxmem)
937 return 0;
938
939 if (type == 1) {
940 /*
941 * Mapping local DRAM into GATT.
942 */
943 if (isc->chiptype != CHIP_I810 )
944 return 0;
945 if (size != isc->dcache_size)
946 return 0;
947 } else if (type == 2) {
948 /*
949 * Bogus mapping for the hardware cursor.
950 */
951 if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE)
952 return 0;
953 }
954
955 mem = malloc(sizeof *mem, M_AGP, M_WAITOK|M_ZERO);
956 if (mem == NULL)
957 return NULL;
958 mem->am_id = sc->as_nextid++;
959 mem->am_size = size;
960 mem->am_type = type;
961
962 if (type == 2) {
963 /*
964 * Allocate and wire down the memory now so that we can
965 * get its physical address.
966 */
967 mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_AGP,
968 M_WAITOK);
969 if (mem->am_dmaseg == NULL) {
970 free(mem, M_AGP);
971 return NULL;
972 }
973 if (agp_alloc_dmamem(sc->as_dmat, size, 0,
974 &mem->am_dmamap, &mem->am_virtual, &mem->am_physical,
975 mem->am_dmaseg, 1, &mem->am_nseg) != 0) {
976 free(mem->am_dmaseg, M_AGP);
977 free(mem, M_AGP);
978 return NULL;
979 }
980 memset(mem->am_virtual, 0, size);
981 } else if (type != 1) {
982 if (bus_dmamap_create(sc->as_dmat, size, size / PAGE_SIZE + 1,
983 size, 0, BUS_DMA_NOWAIT,
984 &mem->am_dmamap) != 0) {
985 free(mem, M_AGP);
986 return NULL;
987 }
988 }
989
990 TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link);
991 sc->as_allocated += size;
992
993 return mem;
994 }
995
996 static int
997 agp_i810_free_memory(struct agp_softc *sc, struct agp_memory *mem)
998 {
999 if (mem->am_is_bound)
1000 return EBUSY;
1001
1002 if (mem->am_type == 2) {
1003 agp_free_dmamem(sc->as_dmat, mem->am_size, mem->am_dmamap,
1004 mem->am_virtual, mem->am_dmaseg, mem->am_nseg);
1005 free(mem->am_dmaseg, M_AGP);
1006 }
1007
1008 sc->as_allocated -= mem->am_size;
1009 TAILQ_REMOVE(&sc->as_memory, mem, am_link);
1010 free(mem, M_AGP);
1011 return 0;
1012 }
1013
1014 static int
1015 agp_i810_bind_memory(struct agp_softc *sc, struct agp_memory *mem,
1016 off_t offset)
1017 {
1018 struct agp_i810_softc *isc = sc->as_chipc;
1019 u_int32_t regval, i;
1020
1021 if (mem->am_is_bound != 0)
1022 return EINVAL;
1023
1024 /*
1025 * XXX evil hack: the PGTBL_CTL appearently gets overwritten by the
1026 * X server for mysterious reasons which leads to crashes if we write
1027 * to the GTT through the MMIO window.
1028 * Until the issue is solved, simply restore it.
1029 */
1030 regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL);
1031 if (regval != (isc->gatt->ag_physical | 1)) {
1032 printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n",
1033 regval);
1034 bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL,
1035 isc->gatt->ag_physical | 1);
1036 }
1037
1038 if (mem->am_type == 2) {
1039 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
1040 agp_i810_bind_page(sc, offset + i,
1041 mem->am_physical + i);
1042 mem->am_offset = offset;
1043 mem->am_is_bound = 1;
1044 return 0;
1045 }
1046
1047 if (mem->am_type != 1)
1048 return agp_generic_bind_memory(sc, mem, offset);
1049
1050 if (isc->chiptype != CHIP_I810)
1051 return EINVAL;
1052
1053 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
1054 agp_i810_write_gtt_entry(isc, i, i | 3);
1055 mem->am_is_bound = 1;
1056 return 0;
1057 }
1058
1059 static int
1060 agp_i810_unbind_memory(struct agp_softc *sc, struct agp_memory *mem)
1061 {
1062 struct agp_i810_softc *isc = sc->as_chipc;
1063 u_int32_t i;
1064
1065 if (mem->am_is_bound == 0)
1066 return EINVAL;
1067
1068 if (mem->am_type == 2) {
1069 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
1070 agp_i810_unbind_page(sc, mem->am_offset + i);
1071 mem->am_offset = 0;
1072 mem->am_is_bound = 0;
1073 return 0;
1074 }
1075
1076 if (mem->am_type != 1)
1077 return agp_generic_unbind_memory(sc, mem);
1078
1079 if (isc->chiptype != CHIP_I810)
1080 return EINVAL;
1081
1082 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
1083 agp_i810_write_gtt_entry(isc, i, 0);
1084 mem->am_is_bound = 0;
1085 return 0;
1086 }
1087
1088 static bool
1089 agp_i810_resume(device_t dv, const pmf_qual_t *qual)
1090 {
1091 struct agp_softc *sc = device_private(dv);
1092 struct agp_i810_softc *isc = sc->as_chipc;
1093
1094 isc->pgtblctl = READ4(AGP_I810_PGTBL_CTL);
1095 agp_flush_cache();
1096
1097 return true;
1098 }
1099