FreeBSD/Linux Kernel Cross Reference
sys/pci/agp_i810.c
1 /*-
2 * Copyright (c) 2000 Doug Rabson
3 * Copyright (c) 2000 Ruslan Ermilov
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD$
28 */
29
30 /*
31 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
32 */
33
34 #include "opt_bus.h"
35 #include "opt_pci.h"
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
40 #include <sys/kernel.h>
41 #include <sys/bus.h>
42 #include <sys/lock.h>
43
44 #include <pci/pcivar.h>
45 #include <pci/pcireg.h>
46 #include <pci/agppriv.h>
47 #include <pci/agpreg.h>
48
49 #include <vm/vm.h>
50 #include <vm/vm_object.h>
51 #include <vm/vm_page.h>
52 #include <vm/vm_pageout.h>
53 #include <vm/pmap.h>
54
55 #include <machine/bus.h>
56 #include <machine/resource.h>
57 #include <sys/rman.h>
58
59 MALLOC_DECLARE(M_AGP);
60
61 #define READ1(off) bus_space_read_1(sc->bst, sc->bsh, off)
62 #define READ4(off) bus_space_read_4(sc->bst, sc->bsh, off)
63 #define WRITE4(off,v) bus_space_write_4(sc->bst, sc->bsh, off, v)
64
65 #define CHIP_I810 0 /* i810/i815 */
66 #define CHIP_I830 1 /* 830M/845G */
67 #define CHIP_I855 2 /* 852GM/855GM/865G */
68
69 struct agp_i810_softc {
70 struct agp_softc agp;
71 u_int32_t initial_aperture; /* aperture size at startup */
72 struct agp_gatt *gatt;
73 int chiptype; /* i810-like or i830 */
74 u_int32_t dcache_size; /* i810 only */
75 u_int32_t stolen; /* number of i830/845 gtt entries for stolen memory */
76 device_t bdev; /* bridge device */
77 struct resource *regs; /* memory mapped GC registers */
78 bus_space_tag_t bst; /* bus_space tag */
79 bus_space_handle_t bsh; /* bus_space handle */
80 };
81
82 static const char*
83 agp_i810_match(device_t dev)
84 {
85 if (pci_get_class(dev) != PCIC_DISPLAY
86 || pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
87 return NULL;
88
89 switch (pci_get_devid(dev)) {
90 case 0x71218086:
91 return ("Intel 82810 (i810 GMCH) SVGA controller");
92
93 case 0x71238086:
94 return ("Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller");
95
96 case 0x71258086:
97 return ("Intel 82810E (i810E GMCH) SVGA controller");
98
99 case 0x11328086:
100 return ("Intel 82815 (i815 GMCH) SVGA controller");
101
102 case 0x35778086:
103 return ("Intel 82830M (830M GMCH) SVGA controller");
104
105 case 0x25628086:
106 return ("Intel 82845G (845G GMCH) SVGA controller");
107
108 case 0x35828086:
109 switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
110 case AGP_I855_GME:
111 return ("Intel 82855GME (855GME GMCH) SVGA controller");
112
113 case AGP_I855_GM:
114 return ("Intel 82855GM (855GM GMCH) SVGA controller");
115
116 case AGP_I852_GME:
117 return ("Intel 82852GME (852GME GMCH) SVGA controller");
118
119 case AGP_I852_GM:
120 return ("Intel 82852GM (852GM GMCH) SVGA controller");
121
122 default:
123 return ("Intel 8285xM (85xGM GMCH) SVGA controller");
124 }
125
126 case 0x25728086:
127 return ("Intel 82865G (865G GMCH) SVGA controller");
128 };
129
130 return NULL;
131 }
132
133 /*
134 * Find bridge device.
135 */
136 static device_t
137 agp_i810_find_bridge(device_t dev)
138 {
139 device_t *children, child;
140 int nchildren, i;
141 u_int32_t devid;
142
143 /*
144 * Calculate bridge device's ID.
145 */
146 devid = pci_get_devid(dev);
147 switch (devid) {
148 case 0x71218086:
149 case 0x71238086:
150 case 0x71258086:
151 devid -= 0x10000;
152 break;
153
154 case 0x11328086:
155 case 0x35778086:
156 case 0x25628086:
157 case 0x35828086:
158 case 0x25728086:
159 devid -= 0x20000;
160 break;
161 };
162 if (device_get_children(device_get_parent(dev), &children, &nchildren))
163 return 0;
164
165 for (i = 0; i < nchildren; i++) {
166 child = children[i];
167
168 if (pci_get_devid(child) == devid) {
169 free(children, M_TEMP);
170 return child;
171 }
172 }
173 free(children, M_TEMP);
174 return 0;
175 }
176
177 static int
178 agp_i810_probe(device_t dev)
179 {
180 const char *desc;
181
182 desc = agp_i810_match(dev);
183 if (desc) {
184 device_t bdev;
185 u_int8_t smram;
186 int devid = pci_get_devid(dev);
187
188 bdev = agp_i810_find_bridge(dev);
189 if (!bdev) {
190 if (bootverbose)
191 printf("I810: can't find bridge device\n");
192 return ENXIO;
193 }
194
195 /*
196 * checking whether internal graphics device has been activated.
197 */
198 if ( (devid == 0x71218086 ) ||
199 (devid == 0x71238086 ) ||
200 (devid == 0x71258086 ) ||
201 (devid == 0x11328086 ) ) {
202 smram = pci_read_config(bdev, AGP_I810_SMRAM, 1);
203 if ((smram & AGP_I810_SMRAM_GMS)
204 == AGP_I810_SMRAM_GMS_DISABLED) {
205 if (bootverbose)
206 printf("I810: disabled, not probing\n");
207 return ENXIO;
208 }
209 } else { /* I830MG */
210 unsigned int gcc1;
211 gcc1 = pci_read_config(bdev, AGP_I830_GCC1, 1);
212 if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED) {
213 if (bootverbose)
214 printf("I830: disabled, not probing\n");
215 return ENXIO;
216 }
217 }
218
219 device_verbose(dev);
220 device_set_desc(dev, desc);
221 return 0;
222 }
223
224 return ENXIO;
225 }
226
227 static int
228 agp_i810_attach(device_t dev)
229 {
230 struct agp_i810_softc *sc = device_get_softc(dev);
231 struct agp_gatt *gatt;
232 int error, rid;
233
234 sc->bdev = agp_i810_find_bridge(dev);
235 if (!sc->bdev)
236 return ENOENT;
237
238 error = agp_generic_attach(dev);
239 if (error)
240 return error;
241
242 switch (pci_get_devid(dev)) {
243 case 0x71218086:
244 case 0x71238086:
245 case 0x71258086:
246 case 0x11328086:
247 sc->chiptype = CHIP_I810;
248 break;
249 case 0x35778086:
250 case 0x25628086:
251 sc->chiptype = CHIP_I830;
252 break;
253 case 0x35828086:
254 case 0x25728086:
255 sc->chiptype = CHIP_I855;
256 break;
257 };
258
259 /* Same for i810 and i830 */
260 rid = AGP_I810_MMADR;
261 sc->regs = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
262 0, ~0, 1, RF_ACTIVE);
263 if (!sc->regs) {
264 agp_generic_detach(dev);
265 return ENOMEM;
266 }
267 sc->bst = rman_get_bustag(sc->regs);
268 sc->bsh = rman_get_bushandle(sc->regs);
269
270 sc->initial_aperture = AGP_GET_APERTURE(dev);
271
272 gatt = malloc( sizeof(struct agp_gatt), M_AGP, M_NOWAIT);
273 if (!gatt) {
274 agp_generic_detach(dev);
275 return ENOMEM;
276 }
277 sc->gatt = gatt;
278
279 gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
280
281 if ( sc->chiptype == CHIP_I810 ) {
282 /* Some i810s have on-chip memory called dcache */
283 if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
284 sc->dcache_size = 4 * 1024 * 1024;
285 else
286 sc->dcache_size = 0;
287
288 /* According to the specs the gatt on the i810 must be 64k */
289 gatt->ag_virtual = contigmalloc( 64 * 1024, M_AGP, 0,
290 0, ~0, PAGE_SIZE, 0);
291 if (!gatt->ag_virtual) {
292 if (bootverbose)
293 device_printf(dev, "contiguous allocation failed\n");
294 free(gatt, M_AGP);
295 agp_generic_detach(dev);
296 return ENOMEM;
297 }
298 bzero(gatt->ag_virtual, gatt->ag_entries * sizeof(u_int32_t));
299
300 gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual);
301 agp_flush_cache();
302 /* Install the GATT. */
303 WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1);
304 } else if ( sc->chiptype == CHIP_I830 ) {
305 /* The i830 automatically initializes the 128k gatt on boot. */
306 unsigned int gcc1, pgtblctl;
307
308 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
309 switch (gcc1 & AGP_I830_GCC1_GMS) {
310 case AGP_I830_GCC1_GMS_STOLEN_512:
311 sc->stolen = (512 - 132) * 1024 / 4096;
312 break;
313 case AGP_I830_GCC1_GMS_STOLEN_1024:
314 sc->stolen = (1024 - 132) * 1024 / 4096;
315 break;
316 case AGP_I830_GCC1_GMS_STOLEN_8192:
317 sc->stolen = (8192 - 132) * 1024 / 4096;
318 break;
319 default:
320 sc->stolen = 0;
321 device_printf(dev, "unknown memory configuration, disabling\n");
322 agp_generic_detach(dev);
323 return EINVAL;
324 }
325 if (sc->stolen > 0)
326 device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4);
327 device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024);
328
329 /* GATT address is already in there, make sure it's enabled */
330 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
331 pgtblctl |= 1;
332 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
333
334 gatt->ag_physical = pgtblctl & ~1;
335 } else { /* CHIP_I855 */
336 /* The 855GM automatically initializes the 128k gatt on boot. */
337 unsigned int gcc1, pgtblctl;
338
339 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
340 switch (gcc1 & AGP_I855_GCC1_GMS) {
341 case AGP_I855_GCC1_GMS_STOLEN_1M:
342 sc->stolen = (1024 - 132) * 1024 / 4096;
343 break;
344 case AGP_I855_GCC1_GMS_STOLEN_4M:
345 sc->stolen = (4096 - 132) * 1024 / 4096;
346 break;
347 case AGP_I855_GCC1_GMS_STOLEN_8M:
348 sc->stolen = (8192 - 132) * 1024 / 4096;
349 break;
350 case AGP_I855_GCC1_GMS_STOLEN_16M:
351 sc->stolen = (16384 - 132) * 1024 / 4096;
352 break;
353 case AGP_I855_GCC1_GMS_STOLEN_32M:
354 sc->stolen = (32768 - 132) * 1024 / 4096;
355 break;
356 default:
357 sc->stolen = 0;
358 device_printf(dev, "unknown memory configuration, disabling\n");
359 agp_generic_detach(dev);
360 return EINVAL;
361 }
362 if (sc->stolen > 0)
363 device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4);
364 device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024);
365
366 /* GATT address is already in there, make sure it's enabled */
367 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
368 pgtblctl |= 1;
369 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
370
371 gatt->ag_physical = pgtblctl & ~1;
372 }
373
374 /*
375 * Make sure the chipset can see everything.
376 */
377 agp_flush_cache();
378
379 return 0;
380 }
381
382 static int
383 agp_i810_detach(device_t dev)
384 {
385 struct agp_i810_softc *sc = device_get_softc(dev);
386 int error;
387
388 error = agp_generic_detach(dev);
389 if (error)
390 return error;
391
392 /* Clear the GATT base. */
393 if ( sc->chiptype == CHIP_I810 ) {
394 WRITE4(AGP_I810_PGTBL_CTL, 0);
395 } else {
396 unsigned int pgtblctl;
397 pgtblctl = READ4(AGP_I810_PGTBL_CTL);
398 pgtblctl &= ~1;
399 WRITE4(AGP_I810_PGTBL_CTL, pgtblctl);
400 }
401
402 /* Put the aperture back the way it started. */
403 AGP_SET_APERTURE(dev, sc->initial_aperture);
404
405 if ( sc->chiptype == CHIP_I810 ) {
406 contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP);
407 }
408 free(sc->gatt, M_AGP);
409
410 bus_release_resource(dev, SYS_RES_MEMORY,
411 AGP_I810_MMADR, sc->regs);
412
413 return 0;
414 }
415
416 static u_int32_t
417 agp_i810_get_aperture(device_t dev)
418 {
419 struct agp_i810_softc *sc = device_get_softc(dev);
420
421 if ( sc->chiptype == CHIP_I810 ) {
422 u_int16_t miscc;
423 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
424 if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32)
425 return 32 * 1024 * 1024;
426 else
427 return 64 * 1024 * 1024;
428 } else if ( sc->chiptype == CHIP_I830 ) {
429 unsigned int gcc1;
430
431 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
432 if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
433 return 64 * 1024 * 1024;
434 else
435 return 128 * 1024 * 1024;
436 } else { /* CHIP_I855 */
437 return 128 * 1024 * 1024;
438 }
439 }
440
441 static int
442 agp_i810_set_aperture(device_t dev, u_int32_t aperture)
443 {
444 struct agp_i810_softc *sc = device_get_softc(dev);
445 u_int16_t miscc;
446
447 if ( sc->chiptype == CHIP_I810 ) {
448 /*
449 * Double check for sanity.
450 */
451 if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) {
452 device_printf(dev, "bad aperture size %d\n", aperture);
453 return EINVAL;
454 }
455
456 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
457 miscc &= ~AGP_I810_MISCC_WINSIZE;
458 if (aperture == 32 * 1024 * 1024)
459 miscc |= AGP_I810_MISCC_WINSIZE_32;
460 else
461 miscc |= AGP_I810_MISCC_WINSIZE_64;
462
463 pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2);
464 } else if ( sc->chiptype == CHIP_I830 ) {
465 unsigned int gcc1;
466
467 if (aperture != 64 * 1024 * 1024 && aperture != 128 * 1024 * 1024) {
468 device_printf(dev, "bad aperture size %d\n", aperture);
469 return EINVAL;
470 }
471 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
472 gcc1 &= ~AGP_I830_GCC1_GMASIZE;
473 if (aperture == 64 * 1024 * 1024)
474 gcc1 |= AGP_I830_GCC1_GMASIZE_64;
475 else
476 gcc1 |= AGP_I830_GCC1_GMASIZE_128;
477
478 pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2);
479 } else { /* CHIP_I855 */
480 if (aperture != 128 * 1024 * 1024) {
481 device_printf(dev, "bad aperture size %d\n", aperture);
482 return EINVAL;
483 }
484 }
485
486 return 0;
487 }
488
489 static int
490 agp_i810_bind_page(device_t dev, int offset, vm_offset_t physical)
491 {
492 struct agp_i810_softc *sc = device_get_softc(dev);
493
494 if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
495 device_printf(dev, "failed: offset is 0x%08x, shift is %d, entries is %d\n", offset, AGP_PAGE_SHIFT, sc->gatt->ag_entries);
496 return EINVAL;
497 }
498
499 if ( sc->chiptype != CHIP_I810 ) {
500 if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) {
501 device_printf(dev, "trying to bind into stolen memory");
502 return EINVAL;
503 }
504 }
505
506 WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, physical | 1);
507 return 0;
508 }
509
510 static int
511 agp_i810_unbind_page(device_t dev, int offset)
512 {
513 struct agp_i810_softc *sc = device_get_softc(dev);
514
515 if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
516 return EINVAL;
517
518 if ( sc->chiptype != CHIP_I810 ) {
519 if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) {
520 device_printf(dev, "trying to unbind from stolen memory");
521 return EINVAL;
522 }
523 }
524
525 WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, 0);
526 return 0;
527 }
528
529 /*
530 * Writing via memory mapped registers already flushes all TLBs.
531 */
532 static void
533 agp_i810_flush_tlb(device_t dev)
534 {
535 }
536
537 static int
538 agp_i810_enable(device_t dev, u_int32_t mode)
539 {
540
541 return 0;
542 }
543
544 static struct agp_memory *
545 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
546 {
547 struct agp_i810_softc *sc = device_get_softc(dev);
548 struct agp_memory *mem;
549
550 if ((size & (AGP_PAGE_SIZE - 1)) != 0)
551 return 0;
552
553 if (sc->agp.as_allocated + size > sc->agp.as_maxmem)
554 return 0;
555
556 if (type == 1) {
557 /*
558 * Mapping local DRAM into GATT.
559 */
560 if ( sc->chiptype != CHIP_I810 )
561 return 0;
562 if (size != sc->dcache_size)
563 return 0;
564 } else if (type == 2) {
565 /*
566 * Bogus mapping of a single page for the hardware cursor.
567 */
568 if (size != AGP_PAGE_SIZE)
569 return 0;
570 }
571
572 mem = malloc(sizeof *mem, M_AGP, M_WAITOK);
573 mem->am_id = sc->agp.as_nextid++;
574 mem->am_size = size;
575 mem->am_type = type;
576 if (type != 1)
577 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
578 atop(round_page(size)));
579 else
580 mem->am_obj = 0;
581
582 if (type == 2) {
583 /*
584 * Allocate and wire down the page now so that we can
585 * get its physical address.
586 */
587 vm_page_t m;
588 m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_ZERO|VM_ALLOC_RETRY);
589 if ((m->flags & PG_ZERO) == 0)
590 vm_page_zero_fill(m);
591 vm_page_wire(m);
592 mem->am_physical = VM_PAGE_TO_PHYS(m);
593 vm_page_wakeup(m);
594 } else {
595 mem->am_physical = 0;
596 }
597
598 mem->am_offset = 0;
599 mem->am_is_bound = 0;
600 TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
601 sc->agp.as_allocated += size;
602
603 return mem;
604 }
605
606 static int
607 agp_i810_free_memory(device_t dev, struct agp_memory *mem)
608 {
609 struct agp_i810_softc *sc = device_get_softc(dev);
610
611 if (mem->am_is_bound)
612 return EBUSY;
613
614 if (mem->am_type == 2) {
615 /*
616 * Unwire the page which we wired in alloc_memory.
617 */
618 vm_page_t m = vm_page_lookup(mem->am_obj, 0);
619 vm_page_unwire(m, 0);
620 }
621
622 sc->agp.as_allocated -= mem->am_size;
623 TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
624 if (mem->am_obj)
625 vm_object_deallocate(mem->am_obj);
626 free(mem, M_AGP);
627 return 0;
628 }
629
630 static int
631 agp_i810_bind_memory(device_t dev, struct agp_memory *mem,
632 vm_offset_t offset)
633 {
634 struct agp_i810_softc *sc = device_get_softc(dev);
635 vm_offset_t i;
636
637 if (mem->am_type != 1)
638 return agp_generic_bind_memory(dev, mem, offset);
639
640 if ( sc->chiptype != CHIP_I810 )
641 return EINVAL;
642
643 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
644 WRITE4(AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4,
645 i | 3);
646 }
647
648 return 0;
649 }
650
651 static int
652 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
653 {
654 struct agp_i810_softc *sc = device_get_softc(dev);
655 vm_offset_t i;
656
657 if (mem->am_type != 1)
658 return agp_generic_unbind_memory(dev, mem);
659
660 if ( sc->chiptype != CHIP_I810 )
661 return EINVAL;
662
663 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
664 WRITE4(AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0);
665
666 return 0;
667 }
668
669 static device_method_t agp_i810_methods[] = {
670 /* Device interface */
671 DEVMETHOD(device_probe, agp_i810_probe),
672 DEVMETHOD(device_attach, agp_i810_attach),
673 DEVMETHOD(device_detach, agp_i810_detach),
674 DEVMETHOD(device_shutdown, bus_generic_shutdown),
675 DEVMETHOD(device_suspend, bus_generic_suspend),
676 DEVMETHOD(device_resume, bus_generic_resume),
677
678 /* AGP interface */
679 DEVMETHOD(agp_get_aperture, agp_i810_get_aperture),
680 DEVMETHOD(agp_set_aperture, agp_i810_set_aperture),
681 DEVMETHOD(agp_bind_page, agp_i810_bind_page),
682 DEVMETHOD(agp_unbind_page, agp_i810_unbind_page),
683 DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb),
684 DEVMETHOD(agp_enable, agp_i810_enable),
685 DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory),
686 DEVMETHOD(agp_free_memory, agp_i810_free_memory),
687 DEVMETHOD(agp_bind_memory, agp_i810_bind_memory),
688 DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory),
689
690 { 0, 0 }
691 };
692
693 static driver_t agp_i810_driver = {
694 "agp",
695 agp_i810_methods,
696 sizeof(struct agp_i810_softc),
697 };
698
699 static devclass_t agp_devclass;
700
701 DRIVER_MODULE(agp_i810, pci, agp_i810_driver, agp_devclass, 0, 0);
Cache object: 15fac2c135464486423ac62649c4ee00
|