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