xref: /netbsd-src/sys/dev/pci/agp_i810.c (revision daf6c4152fcddc27c445489775ed1f66ab4ea9a9)
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