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