1 --- linux/include/linux/agp_backend.h.newagpdist Fri Feb 11 14:50:45 2000
2 +++ linux/include/linux/agp_backend.h Fri Feb 11 14:50:45 2000
5 + * AGPGART module version 0.99
6 + * Copyright (C) 1999 Jeff Hartmann
7 + * Copyright (C) 1999 Precision Insight
8 + * Copyright (C) 1999 Xi Graphics
10 + * Permission is hereby granted, free of charge, to any person obtaining a
11 + * copy of this software and associated documentation files (the "Software"),
12 + * to deal in the Software without restriction, including without limitation
13 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 + * and/or sell copies of the Software, and to permit persons to whom the
15 + * Software is furnished to do so, subject to the following conditions:
17 + * The above copyright notice and this permission notice shall be included
18 + * in all copies or substantial portions of the Software.
20 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 + * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
24 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
26 + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 +#ifndef _AGP_BACKEND_H
31 +#define _AGP_BACKEND_H 1
41 +#define AGPGART_VERSION_MAJOR 0
42 +#define AGPGART_VERSION_MINOR 99
62 +typedef struct _agp_version {
67 +typedef struct _agp_kern_info {
68 + agp_version version;
69 + struct pci_dev *device;
70 + enum chipset_type chipset;
74 + int max_memory; /* In pages */
79 + * The agp_memory structure has information
80 + * about the block of agp memory allocated.
81 + * A caller may manipulate the next and prev
82 + * pointers to link each allocated item into
83 + * a list. These pointers are ignored by the
84 + * backend. Everything else should never be
85 + * written to, but the caller may read any of
86 + * the items to detrimine the status of this
87 + * block of agp memory.
91 +typedef struct _agp_memory {
93 + struct _agp_memory *next;
94 + struct _agp_memory *prev;
96 + int num_scratch_pages;
97 + unsigned long *memory;
104 +#define AGP_NORMAL_MEMORY 0
106 +extern void agp_free_memory(agp_memory *);
109 + * void agp_free_memory(agp_memory *curr) :
111 + * This function frees memory associated with
112 + * an agp_memory pointer. It is the only function
113 + * that can be called when the backend is not owned
114 + * by the caller. (So it can free memory on client
117 + * It takes an agp_memory pointer as an argument.
121 +extern agp_memory *agp_allocate_memory(size_t, u32);
124 + * agp_memory *agp_allocate_memory(size_t page_count, u32 type) :
126 + * This function allocates a group of pages of
129 + * It takes a size_t argument of the number of pages, and
130 + * an u32 argument of the type of memory to be allocated.
131 + * Every agp bridge device will allow you to allocate
132 + * AGP_NORMAL_MEMORY which maps to physical ram. Any other
133 + * type is device dependant.
135 + * It returns NULL whenever memory is unavailable.
139 +extern void agp_copy_info(agp_kern_info *);
142 + * void agp_copy_info(agp_kern_info *info) :
144 + * This function copies information about the
145 + * agp bridge device and the state of the agp
146 + * backend into an agp_kern_info pointer.
148 + * It takes an agp_kern_info pointer as an
149 + * argument. The caller should insure that
150 + * this pointer is valid.
154 +extern int agp_bind_memory(agp_memory *, off_t);
157 + * int agp_bind_memory(agp_memory *curr, off_t pg_start) :
159 + * This function binds an agp_memory structure
160 + * into the graphics aperture translation table.
162 + * It takes an agp_memory pointer and an offset into
163 + * the graphics aperture translation table as arguments
165 + * It returns -EINVAL if the pointer == NULL.
166 + * It returns -EBUSY if the area of the table
167 + * requested is already in use.
171 +extern int agp_unbind_memory(agp_memory *);
174 + * int agp_unbind_memory(agp_memory *curr) :
176 + * This function removes an agp_memory structure
177 + * from the graphics aperture translation table.
179 + * It takes an agp_memory pointer as an argument.
181 + * It returns -EINVAL if this piece of agp_memory
182 + * is not currently bound to the graphics aperture
183 + * translation table or if the agp_memory
188 +extern void agp_enable(u32);
191 + * void agp_enable(u32 mode) :
193 + * This function initializes the agp point-to-point
196 + * It takes an agp mode register as an argument
200 +extern int agp_backend_acquire(void);
203 + * int agp_backend_acquire(void) :
205 + * This Function attempts to acquire the agp
208 + * returns -EBUSY if agp is in use,
209 + * returns 0 if the caller owns the agp backend
212 +extern void agp_backend_release(void);
215 + * void agp_backend_release(void) :
217 + * This Function releases the lock on the agp
220 + * The caller must insure that the graphics
221 + * aperture translation table is read for use
222 + * by another entity. (Ensure that all memory
223 + * it bound is unbound.)
227 +#endif /* _AGP_BACKEND_H */
228 --- linux/include/linux/agpgart.h.newagpdist Fri Feb 11 14:50:45 2000
229 +++ linux/include/linux/agpgart.h Fri Feb 11 14:50:45 2000
232 + * AGPGART module version 0.99
233 + * Copyright (C) 1999 Jeff Hartmann
234 + * Copyright (C) 1999 Precision Insight
235 + * Copyright (C) 1999 Xi Graphics
237 + * Permission is hereby granted, free of charge, to any person obtaining a
238 + * copy of this software and associated documentation files (the "Software"),
239 + * to deal in the Software without restriction, including without limitation
240 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
241 + * and/or sell copies of the Software, and to permit persons to whom the
242 + * Software is furnished to do so, subject to the following conditions:
244 + * The above copyright notice and this permission notice shall be included
245 + * in all copies or substantial portions of the Software.
247 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
248 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
249 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
250 + * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
251 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
252 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
253 + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
260 +#define AGPIOC_BASE 'A'
261 +#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, agp_info*)
262 +#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1)
263 +#define AGPIOC_RELEASE _IO (AGPIOC_BASE, 2)
264 +#define AGPIOC_SETUP _IOW (AGPIOC_BASE, 3, agp_setup*)
265 +#define AGPIOC_RESERVE _IOW (AGPIOC_BASE, 4, agp_region*)
266 +#define AGPIOC_PROTECT _IOW (AGPIOC_BASE, 5, agp_region*)
267 +#define AGPIOC_ALLOCATE _IOWR(AGPIOC_BASE, 6, agp_allocate*)
268 +#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
269 +#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, agp_bind*)
270 +#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, agp_unbind*)
272 +#define AGP_DEVICE "/dev/agpgart"
283 +#include <linux/types.h>
284 +#include <asm/types.h>
286 +typedef struct _agp_version {
291 +typedef struct _agp_info {
292 + agp_version version; /* version of the driver */
293 + __u32 bridge_id; /* bridge vendor/device */
294 + __u32 agp_mode; /* mode info of bridge */
295 + off_t aper_base; /* base of aperture */
296 + size_t aper_size; /* size of aperture */
297 + size_t pg_total; /* max pages (swap + system) */
298 + size_t pg_system; /* max pages (system) */
299 + size_t pg_used; /* current pages used */
302 +typedef struct _agp_setup {
303 + __u32 agp_mode; /* mode info of bridge */
307 + * The "prot" down below needs still a "sleep" flag somehow ...
309 +typedef struct _agp_segment {
310 + off_t pg_start; /* starting page to populate */
311 + size_t pg_count; /* number of pages */
312 + int prot; /* prot flags for mmap */
315 +typedef struct _agp_region {
316 + pid_t pid; /* pid of process */
317 + size_t seg_count; /* number of segments */
318 + struct _agp_segment *seg_list;
321 +typedef struct _agp_allocate {
322 + int key; /* tag of allocation */
323 + size_t pg_count; /* number of pages */
324 + __u32 type; /* 0 == normal, other devspec */
327 +typedef struct _agp_bind {
328 + int key; /* tag of allocation */
329 + off_t pg_start; /* starting page to populate */
332 +typedef struct _agp_unbind {
333 + int key; /* tag of allocation */
334 + __u32 priority; /* priority for paging out */
337 +#else /* __KERNEL__ */
339 +#define AGPGART_MINOR 175
341 +#define AGP_UNLOCK() up(&(agp_fe.agp_mutex));
342 +#define AGP_LOCK() down(&(agp_fe.agp_mutex));
343 +#define AGP_LOCK_INIT() sema_init(&(agp_fe.agp_mutex), 1)
345 +#ifndef _AGP_BACKEND_H
346 +typedef struct _agp_version {
353 +typedef struct _agp_info {
354 + agp_version version; /* version of the driver */
355 + u32 bridge_id; /* bridge vendor/device */
356 + u32 agp_mode; /* mode info of bridge */
357 + off_t aper_base; /* base of aperture */
358 + size_t aper_size; /* size of aperture */
359 + size_t pg_total; /* max pages (swap + system) */
360 + size_t pg_system; /* max pages (system) */
361 + size_t pg_used; /* current pages used */
364 +typedef struct _agp_setup {
365 + u32 agp_mode; /* mode info of bridge */
369 + * The "prot" down below needs still a "sleep" flag somehow ...
371 +typedef struct _agp_segment {
372 + off_t pg_start; /* starting page to populate */
373 + size_t pg_count; /* number of pages */
374 + int prot; /* prot flags for mmap */
377 +typedef struct _agp_segment_priv {
383 +typedef struct _agp_region {
384 + pid_t pid; /* pid of process */
385 + size_t seg_count; /* number of segments */
386 + struct _agp_segment *seg_list;
389 +typedef struct _agp_allocate {
390 + int key; /* tag of allocation */
391 + size_t pg_count; /* number of pages */
392 + u32 type; /* 0 == normal, other devspec */
395 +typedef struct _agp_bind {
396 + int key; /* tag of allocation */
397 + off_t pg_start; /* starting page to populate */
400 +typedef struct _agp_unbind {
401 + int key; /* tag of allocation */
402 + u32 priority; /* priority for paging out */
405 +typedef struct _agp_client {
406 + struct _agp_client *next;
407 + struct _agp_client *prev;
410 + agp_segment_priv **segments;
413 +typedef struct _agp_controller {
414 + struct _agp_controller *next;
415 + struct _agp_controller *prev;
419 + agp_client *clients;
422 +#define AGP_FF_ALLOW_CLIENT 0
423 +#define AGP_FF_ALLOW_CONTROLLER 1
424 +#define AGP_FF_IS_CLIENT 2
425 +#define AGP_FF_IS_CONTROLLER 3
426 +#define AGP_FF_IS_VALID 4
428 +typedef struct _agp_file_private {
429 + struct _agp_file_private *next;
430 + struct _agp_file_private *prev;
435 +struct agp_front_data {
436 + struct semaphore agp_mutex;
437 + agp_controller *current_controller;
438 + agp_controller *controllers;
439 + agp_file_private *file_priv_list;
440 + u8 used_by_controller;
441 + u8 backend_acquired;
444 +#endif /* __KERNEL__ */
447 --- linux/drivers/char/agp/Makefile.newagpdist Fri Feb 11 14:50:45 2000
448 +++ linux/drivers/char/agp/Makefile Fri Feb 11 14:50:45 2000
451 +# Makefile for the agpgart device driver. This driver adds a user
452 +# space ioctl interface to use agp memory. It also adds a kernel interface
453 +# that other drivers could use to manipulate agp memory.
457 +CFLAGS_agp_backend.o :=
459 +ifdef CONFIG_AGP_I810
460 +CFLAGS_agp_backend.o += -DAGP_BUILD_INTEL_I810
462 +ifdef CONFIG_AGP_INTEL
463 +CFLAGS_agp_backend.o += -DAGP_BUILD_INTEL_GENERIC
465 +ifdef CONFIG_AGP_VIA
466 +CFLAGS_agp_backend.o += -DAGP_BUILD_VIA_GENERIC
468 +ifdef CONFIG_AGP_AMD
469 +CFLAGS_agp_backend.o += -DAGP_BUILD_AMD_IRONGATE
471 +ifdef CONFIG_AGP_SIS
472 +CFLAGS_agp_backend.o += -DAGP_BUILD_SIS_GENERIC
474 +ifdef CONFIG_AGP_ALI
475 +CFLAGS_agp_backend.o += -DAGP_BUILD_ALI_M1541
478 +include $(TOPDIR)/Rules.make
480 +agpgart.o: agp_backend.o agpgart_fe.o
481 + $(LD) $(LD_RFLAG) -r -o $@ agp_backend.o agpgart_fe.o
482 --- linux/drivers/char/agp/agp_backend.c.newagpdist Fri Feb 11 14:50:45 2000
483 +++ linux/drivers/char/agp/agp_backend.c Fri Feb 11 14:50:45 2000
486 + * AGPGART module version 0.99
487 + * Copyright (C) 1999 Jeff Hartmann
488 + * Copyright (C) 1999 Precision Insight
489 + * Copyright (C) 1999 Xi Graphics
491 + * Permission is hereby granted, free of charge, to any person obtaining a
492 + * copy of this software and associated documentation files (the "Software"),
493 + * to deal in the Software without restriction, including without limitation
494 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
495 + * and/or sell copies of the Software, and to permit persons to whom the
496 + * Software is furnished to do so, subject to the following conditions:
498 + * The above copyright notice and this permission notice shall be included
499 + * in all copies or substantial portions of the Software.
501 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
502 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
503 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
504 + * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
505 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
506 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
507 + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
510 +#define EXPORT_SYMTAB
511 +#include <linux/config.h>
512 +#include <linux/version.h>
513 +#include <linux/module.h>
514 +#include <linux/types.h>
515 +#include <linux/kernel.h>
516 +#include <linux/sched.h>
517 +#include <linux/mm.h>
518 +#include <linux/string.h>
519 +#include <linux/errno.h>
520 +#include <linux/malloc.h>
521 +#include <linux/vmalloc.h>
522 +#include <linux/pci.h>
523 +#include <linux/init.h>
524 +#include <linux/pagemap.h>
525 +#include <linux/miscdevice.h>
526 +#include <asm/system.h>
527 +#include <asm/uaccess.h>
528 +#include <asm/system.h>
530 +#include <asm/page.h>
532 +#include <linux/agp_backend.h>
533 +#include "agp_backendP.h"
535 +static struct agp_bridge_data agp_bridge;
537 +#define CACHE_FLUSH agp_bridge.cache_flush
539 +MODULE_AUTHOR("Jeff Hartmann <jhartmann@precisioninsight.com>");
540 +MODULE_PARM(agp_try_unsupported, "1i");
541 +EXPORT_SYMBOL(agp_free_memory);
542 +EXPORT_SYMBOL(agp_allocate_memory);
543 +EXPORT_SYMBOL(agp_copy_info);
544 +EXPORT_SYMBOL(agp_bind_memory);
545 +EXPORT_SYMBOL(agp_unbind_memory);
546 +EXPORT_SYMBOL(agp_enable);
547 +EXPORT_SYMBOL(agp_backend_acquire);
548 +EXPORT_SYMBOL(agp_backend_release);
550 +static int agp_try_unsupported __initdata = 0;
553 +static atomic_t cpus_waiting;
556 +int agp_backend_acquire(void)
558 + atomic_inc(&(agp_bridge.agp_in_use));
560 + if (atomic_read(&(agp_bridge.agp_in_use)) != 1) {
561 + atomic_dec(&(agp_bridge.agp_in_use));
568 +void agp_backend_release(void)
570 + atomic_dec(&(agp_bridge.agp_in_use));
574 +static void flush_cache(void)
576 + asm volatile ("wbinvd":::"memory");
580 +static void ipi_handler(void *null)
583 + atomic_dec(&cpus_waiting);
584 + while (atomic_read(&cpus_waiting) > 0)
588 +static void smp_flush_cache(void)
590 + atomic_set(&cpus_waiting, smp_num_cpus - 1);
591 + if (smp_call_function(ipi_handler, NULL, 1, 0) != 0)
592 + panic("agpgart: timed out waiting for the other CPUs!\n");
594 + while (atomic_read(&cpus_waiting) > 0)
600 + * Basic Page Allocation Routines -
601 + * These routines handle page allocation
602 + * and by default they reserve the allocated
603 + * memory. They also handle incrementing the
604 + * current_memory_agp value, Which is checked
605 + * against a maximum value.
608 +static void *agp_alloc_page(void)
612 + pt = (void *) __get_free_page(GFP_KERNEL);
616 + atomic_inc(&(mem_map[MAP_NR(pt)].count));
617 + set_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
618 + atomic_inc(&(agp_bridge.current_memory_agp));
622 +static void agp_destroy_page(void *pt)
627 + atomic_dec(&(mem_map[MAP_NR(pt)].count));
628 + clear_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
629 + free_page((unsigned long) pt);
630 + atomic_dec(&(agp_bridge.current_memory_agp));
633 +/* End Basic Page Allocation Routines */
636 + * Generic routines for handling agp_memory structures -
637 + * They use the basic page allocation routines to do the
638 + * brunt of the work.
641 +#define MAXKEY (4096 * 32)
643 +static void agp_free_key(int key)
649 + if (key < MAXKEY) {
650 + clear_bit(key, agp_bridge.key_list);
654 +static int agp_get_key(void)
658 + bit = find_first_zero_bit(agp_bridge.key_list, MAXKEY);
659 + if (bit < MAXKEY) {
660 + set_bit(bit, agp_bridge.key_list);
666 +static agp_memory *agp_create_memory(int scratch_pages)
670 + new = kmalloc(sizeof(agp_memory), GFP_KERNEL);
675 + memset(new, 0, sizeof(agp_memory));
676 + new->key = agp_get_key();
678 + if (new->key < 0) {
682 + new->memory = vmalloc(PAGE_SIZE * scratch_pages);
684 + if (new->memory == NULL) {
685 + agp_free_key(new->key);
689 + new->num_scratch_pages = scratch_pages;
693 +void agp_free_memory(agp_memory * curr)
697 + if (curr == NULL) {
700 + if (curr->is_bound == TRUE) {
701 + agp_unbind_memory(curr);
703 + if (curr->type != 0) {
704 + agp_bridge.free_by_type(curr);
708 + if (curr->page_count != 0) {
709 + for (i = 0; i < curr->page_count; i++) {
710 + curr->memory[i] &= ~(0x00000fff);
711 + agp_destroy_page((void *) phys_to_virt(curr->memory[i]));
714 + agp_free_key(curr->key);
715 + vfree(curr->memory);
720 +#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
722 +agp_memory *agp_allocate_memory(size_t page_count, u32 type)
728 + if ((atomic_read(&(agp_bridge.current_memory_agp)) + page_count) >
729 + agp_bridge.max_memory_agp) {
733 + new = agp_bridge.alloc_by_type(page_count, type);
736 + scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
738 + new = agp_create_memory(scratch_pages);
743 + for (i = 0; i < page_count; i++) {
744 + new->memory[i] = (unsigned long) agp_alloc_page();
746 + if ((void *) new->memory[i] == NULL) {
747 + /* Free this structure */
748 + agp_free_memory(new);
752 + agp_bridge.mask_memory(virt_to_phys((void *) new->memory[i]), type);
760 +/* End - Generic routines for handling agp_memory structures */
762 +static int agp_return_size(void)
767 + temp = agp_bridge.current_size;
769 + switch (agp_bridge.size_type) {
771 + current_size = ((aper_size_info_8 *) temp)->size;
773 + case U16_APER_SIZE:
774 + current_size = ((aper_size_info_16 *) temp)->size;
776 + case U32_APER_SIZE:
777 + current_size = ((aper_size_info_32 *) temp)->size;
779 + case FIXED_APER_SIZE:
780 + current_size = ((aper_size_info_fixed *) temp)->size;
787 + return current_size;
790 +/* Routine to copy over information structure */
792 +void agp_copy_info(agp_kern_info * info)
794 + memset(info, 0, sizeof(agp_kern_info));
795 + info->version.major = agp_bridge.version->major;
796 + info->version.minor = agp_bridge.version->minor;
797 + info->device = agp_bridge.dev;
798 + info->chipset = agp_bridge.type;
799 + info->mode = agp_bridge.mode;
800 + info->aper_base = agp_bridge.gart_bus_addr;
801 + info->aper_size = agp_return_size();
802 + info->max_memory = agp_bridge.max_memory_agp;
803 + info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
806 +/* End - Routine to copy over information structure */
809 + * Routines for handling swapping of agp_memory into the GATT -
810 + * These routines take agp_memory and insert them into the GATT.
811 + * They call device specific routines to actually write to the GATT.
814 +int agp_bind_memory(agp_memory * curr, off_t pg_start)
818 + if ((curr == NULL) || (curr->is_bound == TRUE)) {
821 + if (curr->is_flushed == FALSE) {
823 + curr->is_flushed = TRUE;
825 + ret_val = agp_bridge.insert_memory(curr, pg_start, curr->type);
827 + if (ret_val != 0) {
830 + curr->is_bound = TRUE;
831 + curr->pg_start = pg_start;
835 +int agp_unbind_memory(agp_memory * curr)
839 + if (curr == NULL) {
842 + if (curr->is_bound != TRUE) {
845 + ret_val = agp_bridge.remove_memory(curr, curr->pg_start, curr->type);
847 + if (ret_val != 0) {
850 + curr->is_bound = FALSE;
851 + curr->pg_start = 0;
855 +/* End - Routines for handling swapping of agp_memory into the GATT */
858 + * Driver routines - start
859 + * Currently this module supports the
860 + * i810, 440lx, 440bx, 440gx, via vp3, via mvp3,
861 + * amd irongate, ALi M1541 and generic support for the
865 +/* Generic Agp routines - Start */
867 +static void agp_generic_agp_enable(u32 mode)
869 + struct pci_dev *device = NULL;
870 + u32 command, scratch, cap_id;
873 + pci_read_config_dword(agp_bridge.dev,
874 + agp_bridge.capndx + 4,
878 + * PASS1: go throu all devices that claim to be
879 + * AGP devices and collect their data.
882 + while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, device)) != NULL) {
883 + pci_read_config_dword(device, 0x04, &scratch);
885 + if (!(scratch & 0x00100000))
888 + pci_read_config_byte(device, 0x34, &cap_ptr);
890 + if (cap_ptr != 0x00) {
892 + pci_read_config_dword(device, cap_ptr, &cap_id);
894 + if ((cap_id & 0xff) != 0x02)
895 + cap_ptr = (cap_id >> 8) & 0xff;
897 + while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
899 + if (cap_ptr != 0x00) {
901 + * Ok, here we have a AGP device. Disable impossible settings,
902 + * and adjust the readqueue to the minimum.
905 + pci_read_config_dword(device, cap_ptr + 4, &scratch);
907 + /* adjust RQ depth */
909 + ((command & ~0xff000000) |
910 + min((mode & 0xff000000), min((command & 0xff000000), (scratch & 0xff000000))));
912 + /* disable SBA if it's not supported */
913 + if (!((command & 0x00000200) && (scratch & 0x00000200) && (mode & 0x00000200)))
914 + command &= ~0x00000200;
916 + /* disable FW if it's not supported */
917 + if (!((command & 0x00000010) && (scratch & 0x00000010) && (mode & 0x00000010)))
918 + command &= ~0x00000010;
920 + if (!((command & 4) && (scratch & 4) && (mode & 4)))
921 + command &= ~0x00000004;
923 + if (!((command & 2) && (scratch & 2) && (mode & 2)))
924 + command &= ~0x00000002;
926 + if (!((command & 1) && (scratch & 1) && (mode & 1)))
927 + command &= ~0x00000001;
931 + * PASS2: Figure out the 4X/2X/1X setting and enable the
932 + * target (our motherboard chipset).
936 + command &= ~3; /* 4X */
939 + command &= ~5; /* 2X */
942 + command &= ~6; /* 1X */
944 + command |= 0x00000100;
946 + pci_write_config_dword(agp_bridge.dev,
947 + agp_bridge.capndx + 8,
951 + * PASS3: Go throu all AGP devices and update the
952 + * command registers.
955 + while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, device)) != NULL) {
956 + pci_read_config_dword(device, 0x04, &scratch);
958 + if (!(scratch & 0x00100000))
961 + pci_read_config_byte(device, 0x34, &cap_ptr);
963 + if (cap_ptr != 0x00) {
965 + pci_read_config_dword(device, cap_ptr, &cap_id);
967 + if ((cap_id & 0xff) != 0x02)
968 + cap_ptr = (cap_id >> 8) & 0xff;
970 + while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
972 + if (cap_ptr != 0x00)
973 + pci_write_config_dword(device, cap_ptr + 8, command);
977 +static int agp_generic_create_gatt_table(void)
988 + i = agp_bridge.aperture_size_idx;
989 + temp = agp_bridge.current_size;
990 + size = page_order = num_entries = 0;
992 + if (agp_bridge.size_type != FIXED_APER_SIZE) {
994 + switch (agp_bridge.size_type) {
996 + size = ((aper_size_info_8 *) temp)->size;
997 + page_order = ((aper_size_info_8 *) temp)->page_order;
998 + num_entries = ((aper_size_info_8 *) temp)->num_entries;
1000 + case U16_APER_SIZE:
1001 + size = ((aper_size_info_16 *) temp)->size;
1002 + page_order = ((aper_size_info_16 *) temp)->page_order;
1003 + num_entries = ((aper_size_info_16 *) temp)->num_entries;
1005 + case U32_APER_SIZE:
1006 + size = ((aper_size_info_32 *) temp)->size;
1007 + page_order = ((aper_size_info_32 *) temp)->page_order;
1008 + num_entries = ((aper_size_info_32 *) temp)->num_entries;
1010 + /* This case will never really happen */
1011 + case FIXED_APER_SIZE:
1013 + size = page_order = num_entries = 0;
1017 + table = (char *) __get_free_pages(GFP_KERNEL, page_order);
1019 + if (table == NULL) {
1022 + switch (agp_bridge.size_type) {
1023 + case U8_APER_SIZE:
1024 + agp_bridge.current_size = (((aper_size_info_8 *) agp_bridge.aperture_sizes) + i);
1026 + case U16_APER_SIZE:
1027 + agp_bridge.current_size = (((aper_size_info_16 *) agp_bridge.aperture_sizes) + i);
1029 + case U32_APER_SIZE:
1030 + agp_bridge.current_size = (((aper_size_info_32 *) agp_bridge.aperture_sizes) + i);
1032 + /* This case will never really happen */
1033 + case FIXED_APER_SIZE:
1035 + size = page_order = num_entries = 0;
1039 + agp_bridge.aperture_size_idx = i;
1041 + } while ((table == NULL) && (i < agp_bridge.num_aperture_sizes));
1043 + size = ((aper_size_info_fixed *) temp)->size;
1044 + page_order = ((aper_size_info_fixed *) temp)->page_order;
1045 + num_entries = ((aper_size_info_fixed *) temp)->num_entries;
1046 + table = (char *) __get_free_pages(GFP_KERNEL, page_order);
1049 + if (table == NULL) {
1052 + table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
1054 + for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
1055 + set_bit(PG_reserved, &mem_map[i].flags);
1058 + agp_bridge.gatt_table_real = (unsigned long *) table;
1060 + agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
1061 + (PAGE_SIZE * (1 << page_order)));
1064 + if (agp_bridge.gatt_table == NULL) {
1065 + for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
1066 + clear_bit(PG_reserved, &mem_map[i].flags);
1069 + free_pages((unsigned long) table, page_order);
1073 + agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real);
1075 + for (i = 0; i < num_entries; i++) {
1076 + agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
1082 +static int agp_generic_free_gatt_table(void)
1086 + char *table, *table_end;
1089 + temp = agp_bridge.current_size;
1091 + switch (agp_bridge.size_type) {
1092 + case U8_APER_SIZE:
1093 + page_order = ((aper_size_info_8 *) temp)->page_order;
1095 + case U16_APER_SIZE:
1096 + page_order = ((aper_size_info_16 *) temp)->page_order;
1098 + case U32_APER_SIZE:
1099 + page_order = ((aper_size_info_32 *) temp)->page_order;
1101 + case FIXED_APER_SIZE:
1102 + page_order = ((aper_size_info_fixed *) temp)->page_order;
1109 + /* Do not worry about freeing memory, because if this is
1110 + * called, then all agp memory is deallocated and removed
1114 + iounmap(agp_bridge.gatt_table);
1115 + table = (char *) agp_bridge.gatt_table_real;
1116 + table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
1118 + for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
1119 + clear_bit(PG_reserved, &mem_map[i].flags);
1122 + free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
1126 +static int agp_generic_insert_memory(agp_memory * mem,
1127 + off_t pg_start, int type)
1129 + int i, j, num_entries;
1132 + temp = agp_bridge.current_size;
1134 + switch (agp_bridge.size_type) {
1135 + case U8_APER_SIZE:
1136 + num_entries = ((aper_size_info_8 *) temp)->num_entries;
1138 + case U16_APER_SIZE:
1139 + num_entries = ((aper_size_info_16 *) temp)->num_entries;
1141 + case U32_APER_SIZE:
1142 + num_entries = ((aper_size_info_32 *) temp)->num_entries;
1144 + case FIXED_APER_SIZE:
1145 + num_entries = ((aper_size_info_fixed *) temp)->num_entries;
1152 + if (type != 0 || mem->type != 0) {
1153 + /* The generic routines know nothing of memory types */
1156 + if ((pg_start + mem->page_count) > num_entries) {
1161 + while (j < (pg_start + mem->page_count)) {
1162 + if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
1168 + if (mem->is_flushed == FALSE) {
1170 + mem->is_flushed = TRUE;
1172 + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
1173 + agp_bridge.gatt_table[j] = mem->memory[i];
1176 + agp_bridge.tlb_flush(mem);
1180 +static int agp_generic_remove_memory(agp_memory * mem, off_t pg_start,
1185 + if (type != 0 || mem->type != 0) {
1186 + /* The generic routines know nothing of memory types */
1189 + for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1190 + agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
1193 + agp_bridge.tlb_flush(mem);
1197 +static agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
1202 +static void agp_generic_free_by_type(agp_memory * curr)
1204 + if (curr->memory != NULL) {
1205 + vfree(curr->memory);
1207 + agp_free_key(curr->key);
1211 +void agp_enable(u32 mode)
1213 + agp_bridge.agp_enable(mode);
1216 +/* End - Generic Agp routines */
1218 +#ifdef AGP_BUILD_INTEL_I810
1220 +static aper_size_info_fixed intel_i810_sizes[] =
1223 + /* The 32M mode still requires a 64k gatt */
1227 +#define AGP_DCACHE_MEMORY 1
1229 +static gatt_mask intel_i810_masks[] =
1231 + {I810_PTE_VALID, 0},
1232 + {(I810_PTE_VALID | I810_PTE_LOCAL), AGP_DCACHE_MEMORY}
1235 +static struct _intel_i810_private {
1236 + struct pci_dev *i810_dev; /* device one */
1237 + volatile unsigned char *registers;
1238 + int num_dcache_entries;
1239 +} intel_i810_private;
1241 +static int intel_i810_fetch_size(void)
1244 + aper_size_info_fixed *values;
1246 + pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc);
1247 + values = (aper_size_info_fixed *) agp_bridge.aperture_sizes;
1249 + if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
1250 + printk("agpgart: i810 is disabled\n");
1253 + if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
1254 + agp_bridge.previous_size =
1255 + agp_bridge.current_size = (void *) (values + 1);
1256 + agp_bridge.aperture_size_idx = 1;
1257 + return values[1].size;
1259 + agp_bridge.previous_size =
1260 + agp_bridge.current_size = (void *) (values);
1261 + agp_bridge.aperture_size_idx = 0;
1262 + return values[0].size;
1268 +static int intel_i810_configure(void)
1270 + aper_size_info_fixed *current_size;
1274 + current_size = (aper_size_info_fixed *) agp_bridge.current_size;
1276 + pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
1277 + temp &= 0xfff80000;
1279 + intel_i810_private.registers =
1280 + (volatile unsigned char *) ioremap(temp, 128 * 4096);
1282 + if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
1283 + & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
1284 + /* This will need to be dynamically assigned */
1285 + printk("agpgart: detected 4MB dedicated video ram.\n");
1286 + intel_i810_private.num_dcache_entries = 1024;
1288 + pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
1289 + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1290 + OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
1291 + agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
1294 + if (agp_bridge.needs_scratch_page == TRUE) {
1295 + for (i = 0; i < current_size->num_entries; i++) {
1296 + OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
1297 + agp_bridge.scratch_page);
1303 +static void intel_i810_cleanup(void)
1305 + OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, 0);
1306 + iounmap((void *) intel_i810_private.registers);
1309 +static void intel_i810_tlbflush(agp_memory * mem)
1314 +static void intel_i810_agp_enable(u32 mode)
1319 +static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
1322 + int i, j, num_entries;
1325 + temp = agp_bridge.current_size;
1326 + num_entries = ((aper_size_info_fixed *) temp)->num_entries;
1328 + if ((pg_start + mem->page_count) > num_entries) {
1331 + for (j = pg_start; j < (pg_start + mem->page_count); j++) {
1332 + if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
1337 + if (type != 0 || mem->type != 0) {
1338 + if ((type == AGP_DCACHE_MEMORY) &&
1339 + (mem->type == AGP_DCACHE_MEMORY)) {
1340 + /* special insert */
1342 + for (i = pg_start; i < (pg_start + mem->page_count); i++) {
1343 + OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
1344 + (i * 4096) | I810_PTE_LOCAL | I810_PTE_VALID);
1347 + agp_bridge.tlb_flush(mem);
1352 + if (mem->is_flushed == FALSE) {
1354 + mem->is_flushed = TRUE;
1356 + for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
1357 + OUTREG32(intel_i810_private.registers,
1358 + I810_PTE_BASE + (j * 4), mem->memory[i]);
1361 + agp_bridge.tlb_flush(mem);
1365 +static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
1370 + for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1371 + OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
1372 + agp_bridge.scratch_page);
1375 + agp_bridge.tlb_flush(mem);
1379 +static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
1383 + if (type == AGP_DCACHE_MEMORY) {
1384 + if (pg_count != intel_i810_private.num_dcache_entries) {
1387 + new = agp_create_memory(1);
1389 + if (new == NULL) {
1392 + new->type = AGP_DCACHE_MEMORY;
1393 + new->page_count = pg_count;
1394 + new->num_scratch_pages = 0;
1395 + vfree(new->memory);
1401 +static void intel_i810_free_by_type(agp_memory * curr)
1403 + agp_free_key(curr->key);
1407 +static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
1409 + /* Type checking must be done elsewhere */
1410 + return addr | agp_bridge.masks[type].mask;
1413 +static void intel_i810_setup(struct pci_dev *i810_dev)
1415 + intel_i810_private.i810_dev = i810_dev;
1417 + agp_bridge.masks = intel_i810_masks;
1418 + agp_bridge.num_of_masks = 2;
1419 + agp_bridge.aperture_sizes = (void *) intel_i810_sizes;
1420 + agp_bridge.size_type = FIXED_APER_SIZE;
1421 + agp_bridge.num_aperture_sizes = 2;
1422 + agp_bridge.dev_private_data = (void *) &intel_i810_private;
1423 + agp_bridge.needs_scratch_page = TRUE;
1424 + agp_bridge.configure = intel_i810_configure;
1425 + agp_bridge.fetch_size = intel_i810_fetch_size;
1426 + agp_bridge.cleanup = intel_i810_cleanup;
1427 + agp_bridge.tlb_flush = intel_i810_tlbflush;
1428 + agp_bridge.mask_memory = intel_i810_mask_memory;
1429 + agp_bridge.agp_enable = intel_i810_agp_enable;
1431 + agp_bridge.cache_flush = smp_flush_cache;
1433 + agp_bridge.cache_flush = flush_cache;
1435 + agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1436 + agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1437 + agp_bridge.insert_memory = intel_i810_insert_entries;
1438 + agp_bridge.remove_memory = intel_i810_remove_entries;
1439 + agp_bridge.alloc_by_type = intel_i810_alloc_by_type;
1440 + agp_bridge.free_by_type = intel_i810_free_by_type;
1445 +#ifdef AGP_BUILD_INTEL_GENERIC
1447 +static int intel_fetch_size(void)
1451 + aper_size_info_16 *values;
1453 + pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp);
1454 + (void *) values = agp_bridge.aperture_sizes;
1456 + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1457 + if (temp == values[i].size_value) {
1458 + agp_bridge.previous_size =
1459 + agp_bridge.current_size = (void *) (values + i);
1460 + agp_bridge.aperture_size_idx = i;
1461 + return values[i].size;
1468 +static void intel_tlbflush(agp_memory * mem)
1470 + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200);
1471 + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
1474 +static void intel_cleanup(void)
1478 + pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
1479 + pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
1482 +static int intel_configure(void)
1486 + aper_size_info_16 *current_size;
1488 + current_size = (aper_size_info_16 *) agp_bridge.current_size;
1490 + /* aperture size */
1491 + pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
1493 + /* address to map to */
1494 + pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
1495 + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1497 + /* attbase - aperture base */
1498 + pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
1501 + pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
1503 + /* paccfg/nbxcfg */
1504 + pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
1505 + pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, (temp2 & ~(1 << 10)) | (1 << 9));
1506 + /* clear any possible error conditions */
1507 + pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7);
1511 +static unsigned long intel_mask_memory(unsigned long addr, int type)
1513 + /* Memory type is ignored */
1515 + return addr | agp_bridge.masks[0].mask;
1519 +/* Setup function */
1520 +static gatt_mask intel_generic_masks[] =
1525 +static aper_size_info_16 intel_generic_sizes[7] =
1527 + {256, 65536, 6, 0},
1528 + {128, 32768, 5, 32},
1529 + {64, 16384, 4, 48},
1530 + {32, 8192, 3, 56},
1531 + {16, 4096, 2, 60},
1536 +static void intel_generic_setup(void)
1538 + agp_bridge.masks = intel_generic_masks;
1539 + agp_bridge.num_of_masks = 1;
1540 + agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
1541 + agp_bridge.size_type = U16_APER_SIZE;
1542 + agp_bridge.num_aperture_sizes = 7;
1543 + agp_bridge.dev_private_data = NULL;
1544 + agp_bridge.needs_scratch_page = FALSE;
1545 + agp_bridge.configure = intel_configure;
1546 + agp_bridge.fetch_size = intel_fetch_size;
1547 + agp_bridge.cleanup = intel_cleanup;
1548 + agp_bridge.tlb_flush = intel_tlbflush;
1549 + agp_bridge.mask_memory = intel_mask_memory;
1550 + agp_bridge.agp_enable = agp_generic_agp_enable;
1552 + agp_bridge.cache_flush = smp_flush_cache;
1554 + agp_bridge.cache_flush = flush_cache;
1556 + agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1557 + agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1558 + agp_bridge.insert_memory = agp_generic_insert_memory;
1559 + agp_bridge.remove_memory = agp_generic_remove_memory;
1560 + agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1561 + agp_bridge.free_by_type = agp_generic_free_by_type;
1566 +#ifdef AGP_BUILD_VIA_GENERIC
1568 +static int via_fetch_size(void)
1572 + aper_size_info_8 *values;
1574 + (void *) values = agp_bridge.aperture_sizes;
1575 + pci_read_config_byte(agp_bridge.dev, VIA_APSIZE, &temp);
1576 + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1577 + if (temp == values[i].size_value) {
1578 + agp_bridge.previous_size =
1579 + agp_bridge.current_size = (void *) (values + i);
1580 + agp_bridge.aperture_size_idx = i;
1581 + return values[i].size;
1588 +static int via_configure(void)
1591 + aper_size_info_8 *current_size;
1593 + current_size = (aper_size_info_8 *) agp_bridge.current_size;
1594 + /* aperture size */
1595 + pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, current_size->size_value);
1596 + /* address to map too */
1597 + pci_read_config_dword(agp_bridge.dev, VIA_APBASE, &temp);
1598 + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1600 + /* GART control register */
1601 + pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
1603 + /* attbase - aperture GATT base */
1604 + pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE,
1605 + (agp_bridge.gatt_bus_addr & 0xfffff000) | 3);
1609 +static void via_cleanup(void)
1611 + aper_size_info_8 *previous_size;
1613 + previous_size = (aper_size_info_8 *) agp_bridge.previous_size;
1614 + pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE, 0);
1615 + pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, previous_size->size_value);
1618 +static void via_tlbflush(agp_memory * mem)
1620 + pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000008f);
1621 + pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
1624 +static unsigned long via_mask_memory(unsigned long addr, int type)
1626 + /* Memory type is ignored */
1628 + return addr | agp_bridge.masks[0].mask;
1631 +static aper_size_info_8 via_generic_sizes[7] =
1633 + {256, 65536, 6, 0},
1634 + {128, 32768, 5, 128},
1635 + {64, 16384, 4, 192},
1636 + {32, 8192, 3, 224},
1637 + {16, 4096, 2, 240},
1638 + {8, 2048, 1, 248},
1642 +static gatt_mask via_generic_masks[] =
1647 +static void via_generic_setup(void)
1649 + agp_bridge.masks = via_generic_masks;
1650 + agp_bridge.num_of_masks = 1;
1651 + agp_bridge.aperture_sizes = (void *) via_generic_sizes;
1652 + agp_bridge.size_type = U8_APER_SIZE;
1653 + agp_bridge.num_aperture_sizes = 7;
1654 + agp_bridge.dev_private_data = NULL;
1655 + agp_bridge.needs_scratch_page = FALSE;
1656 + agp_bridge.configure = via_configure;
1657 + agp_bridge.fetch_size = via_fetch_size;
1658 + agp_bridge.cleanup = via_cleanup;
1659 + agp_bridge.tlb_flush = via_tlbflush;
1660 + agp_bridge.mask_memory = via_mask_memory;
1661 + agp_bridge.agp_enable = agp_generic_agp_enable;
1663 + agp_bridge.cache_flush = smp_flush_cache;
1665 + agp_bridge.cache_flush = flush_cache;
1667 + agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1668 + agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1669 + agp_bridge.insert_memory = agp_generic_insert_memory;
1670 + agp_bridge.remove_memory = agp_generic_remove_memory;
1671 + agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1672 + agp_bridge.free_by_type = agp_generic_free_by_type;
1677 +#ifdef AGP_BUILD_SIS_GENERIC
1679 +static int sis_fetch_size(void)
1683 + aper_size_info_8 *values;
1685 + pci_read_config_byte(agp_bridge.dev, SIS_APSIZE, &temp_size);
1686 + (void *) values = agp_bridge.aperture_sizes;
1687 + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1688 + if ((temp_size == values[i].size_value) ||
1689 + ((temp_size & ~(0x03)) == (values[i].size_value & ~(0x03)))) {
1690 + agp_bridge.previous_size =
1691 + agp_bridge.current_size = (void *) (values + i);
1693 + agp_bridge.aperture_size_idx = i;
1694 + return values[i].size;
1702 +static void sis_tlbflush(agp_memory * mem)
1704 + pci_write_config_byte(agp_bridge.dev, SIS_TLBFLUSH, 0x02);
1707 +static int sis_configure(void)
1710 + aper_size_info_8 *current_size;
1712 + current_size = (aper_size_info_8 *) agp_bridge.current_size;
1713 + pci_write_config_byte(agp_bridge.dev, SIS_TLBCNTRL, 0x05);
1714 + pci_read_config_dword(agp_bridge.dev, SIS_APBASE, &temp);
1715 + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1716 + pci_write_config_dword(agp_bridge.dev, SIS_ATTBASE, agp_bridge.gatt_bus_addr);
1717 + pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, current_size->size_value);
1721 +static void sis_cleanup(void)
1723 + aper_size_info_8 *previous_size;
1725 + previous_size = (aper_size_info_8 *) agp_bridge.previous_size;
1726 + pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, (previous_size->size_value & ~(0x03)));
1729 +static unsigned long sis_mask_memory(unsigned long addr, int type)
1731 + /* Memory type is ignored */
1733 + return addr | agp_bridge.masks[0].mask;
1736 +static aper_size_info_8 sis_generic_sizes[7] =
1738 + {256, 65536, 6, 99},
1739 + {128, 32768, 5, 83},
1740 + {64, 16384, 4, 67},
1741 + {32, 8192, 3, 51},
1742 + {16, 4096, 2, 35},
1747 +static gatt_mask sis_generic_masks[] =
1752 +static void sis_generic_setup(void)
1754 + agp_bridge.masks = sis_generic_masks;
1755 + agp_bridge.num_of_masks = 1;
1756 + agp_bridge.aperture_sizes = (void *) sis_generic_sizes;
1757 + agp_bridge.size_type = U8_APER_SIZE;
1758 + agp_bridge.num_aperture_sizes = 7;
1759 + agp_bridge.dev_private_data = NULL;
1760 + agp_bridge.needs_scratch_page = FALSE;
1761 + agp_bridge.configure = sis_configure;
1762 + agp_bridge.fetch_size = sis_fetch_size;
1763 + agp_bridge.cleanup = sis_cleanup;
1764 + agp_bridge.tlb_flush = sis_tlbflush;
1765 + agp_bridge.mask_memory = sis_mask_memory;
1766 + agp_bridge.agp_enable = agp_generic_agp_enable;
1768 + agp_bridge.cache_flush = smp_flush_cache;
1770 + agp_bridge.cache_flush = flush_cache;
1772 + agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1773 + agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1774 + agp_bridge.insert_memory = agp_generic_insert_memory;
1775 + agp_bridge.remove_memory = agp_generic_remove_memory;
1776 + agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1777 + agp_bridge.free_by_type = agp_generic_free_by_type;
1782 +#ifdef AGP_BUILD_AMD_IRONGATE
1784 +static struct _amd_irongate_private {
1785 + volatile unsigned char *registers;
1786 +} amd_irongate_private;
1788 +static int amd_irongate_fetch_size(void)
1792 + aper_size_info_32 *values;
1794 + pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
1795 + temp = (temp & 0x0000000e);
1796 + (void *) values = agp_bridge.aperture_sizes;
1797 + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1798 + if (temp == values[i].size_value) {
1799 + agp_bridge.previous_size =
1800 + agp_bridge.current_size = (void *) (values + i);
1802 + agp_bridge.aperture_size_idx = i;
1803 + return values[i].size;
1810 +static int amd_irongate_configure(void)
1812 + aper_size_info_32 *current_size;
1816 + current_size = (aper_size_info_32 *) agp_bridge.current_size;
1818 + /* Get the memory mapped registers */
1819 + pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp);
1820 + temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1821 + amd_irongate_private.registers = (volatile unsigned char *) ioremap(temp, 4096);
1823 + /* Write out the address of the gatt table */
1824 + OUTREG32(amd_irongate_private.registers, AMD_ATTBASE, agp_bridge.gatt_bus_addr);
1826 + /* Write the Sync register */
1827 + pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80);
1829 + /* Write the enable register */
1830 + enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
1831 + enable_reg = (enable_reg | 0x0004);
1832 + OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
1834 + /* Write out the size register */
1835 + pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
1836 + temp = (((temp & ~(0x0000000e)) | current_size->size_value) | 0x00000001);
1837 + pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
1839 + /* Flush the tlb */
1840 + OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
1842 + /* Get the address for the gart region */
1843 + pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
1844 + temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1845 + agp_bridge.gart_bus_addr = temp;
1849 +static void amd_irongate_cleanup(void)
1851 + aper_size_info_32 *previous_size;
1855 + previous_size = (aper_size_info_32 *) agp_bridge.previous_size;
1857 + enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
1858 + enable_reg = (enable_reg & ~(0x0004));
1859 + OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
1861 + /* Write back the previous size and disable gart translation */
1862 + pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
1863 + temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
1864 + pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
1865 + iounmap((void *) amd_irongate_private.registers);
1869 + * This routine could be implemented by taking the addresses
1870 + * written to the GATT, and flushing them individually. However
1871 + * currently it just flushes the whole table. Which is probably
1872 + * more efficent, since agp_memory blocks can be a large number of
1876 +static void amd_irongate_tlbflush(agp_memory * temp)
1878 + OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
1881 +static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
1883 + /* Only type 0 is supported by the irongate */
1885 + return addr | agp_bridge.masks[0].mask;
1888 +static aper_size_info_32 amd_irongate_sizes[7] =
1890 + {2048, 524288, 9, 0x0000000c},
1891 + {1024, 262144, 8, 0x0000000a},
1892 + {512, 131072, 7, 0x00000008},
1893 + {256, 65536, 6, 0x00000006},
1894 + {128, 32768, 5, 0x00000004},
1895 + {64, 16384, 4, 0x00000002},
1896 + {32, 8192, 3, 0x00000000}
1899 +static gatt_mask amd_irongate_masks[] =
1904 +static void amd_irongate_setup(void)
1906 + agp_bridge.masks = amd_irongate_masks;
1907 + agp_bridge.num_of_masks = 1;
1908 + agp_bridge.aperture_sizes = (void *) amd_irongate_sizes;
1909 + agp_bridge.size_type = U32_APER_SIZE;
1910 + agp_bridge.num_aperture_sizes = 7;
1911 + agp_bridge.dev_private_data = (void *) &amd_irongate_private;
1912 + agp_bridge.needs_scratch_page = FALSE;
1913 + agp_bridge.configure = amd_irongate_configure;
1914 + agp_bridge.fetch_size = amd_irongate_fetch_size;
1915 + agp_bridge.cleanup = amd_irongate_cleanup;
1916 + agp_bridge.tlb_flush = amd_irongate_tlbflush;
1917 + agp_bridge.mask_memory = amd_irongate_mask_memory;
1918 + agp_bridge.agp_enable = agp_generic_agp_enable;
1920 + agp_bridge.cache_flush = smp_flush_cache;
1922 + agp_bridge.cache_flush = flush_cache;
1924 + agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1925 + agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1926 + agp_bridge.insert_memory = agp_generic_insert_memory;
1927 + agp_bridge.remove_memory = agp_generic_remove_memory;
1928 + agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1929 + agp_bridge.free_by_type = agp_generic_free_by_type;
1934 +#ifdef AGP_BUILD_ALI_M1541
1936 +static int ali_fetch_size(void)
1940 + aper_size_info_32 *values;
1942 + pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp);
1943 + temp &= ~(0xfffffff0);
1944 + (void *) values = agp_bridge.aperture_sizes;
1946 + for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1947 + if (temp == values[i].size_value) {
1948 + agp_bridge.previous_size =
1949 + agp_bridge.current_size = (void *) (values + i);
1950 + agp_bridge.aperture_size_idx = i;
1951 + return values[i].size;
1958 +static void ali_tlbflush(agp_memory * mem)
1962 + pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
1963 + pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1964 + ((temp & 0xffffff00) | 0x00000090));
1965 + pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1966 + ((temp & 0xffffff00) | 0x00000010));
1969 +static void ali_cleanup(void)
1971 + aper_size_info_32 *previous_size;
1974 + previous_size = (aper_size_info_32 *) agp_bridge.previous_size;
1976 + pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
1977 + pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1978 + ((temp & 0xffffff00) | 0x00000090));
1979 + pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE, previous_size->size_value);
1982 +static int ali_configure(void)
1985 + aper_size_info_32 *current_size;
1987 + current_size = (aper_size_info_32 *) agp_bridge.current_size;
1989 + /* aperture size and gatt addr */
1990 + pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE,
1991 + agp_bridge.gatt_bus_addr | current_size->size_value);
1994 + pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
1995 + pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1996 + ((temp & 0xffffff00) | 0x00000010));
1998 + /* address to map to */
1999 + pci_read_config_dword(agp_bridge.dev, ALI_APBASE, &temp);
2000 + agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
2004 +static unsigned long ali_mask_memory(unsigned long addr, int type)
2006 + /* Memory type is ignored */
2008 + return addr | agp_bridge.masks[0].mask;
2012 +/* Setup function */
2013 +static gatt_mask ali_generic_masks[] =
2018 +static aper_size_info_32 ali_generic_sizes[7] =
2020 + {256, 65536, 6, 10},
2021 + {128, 32768, 5, 9},
2022 + {64, 16384, 4, 8},
2029 +static void ali_generic_setup(void)
2031 + agp_bridge.masks = ali_generic_masks;
2032 + agp_bridge.num_of_masks = 1;
2033 + agp_bridge.aperture_sizes = (void *) ali_generic_sizes;
2034 + agp_bridge.size_type = U32_APER_SIZE;
2035 + agp_bridge.num_aperture_sizes = 7;
2036 + agp_bridge.dev_private_data = NULL;
2037 + agp_bridge.needs_scratch_page = FALSE;
2038 + agp_bridge.configure = ali_configure;
2039 + agp_bridge.fetch_size = ali_fetch_size;
2040 + agp_bridge.cleanup = ali_cleanup;
2041 + agp_bridge.tlb_flush = ali_tlbflush;
2042 + agp_bridge.mask_memory = ali_mask_memory;
2043 + agp_bridge.agp_enable = agp_generic_agp_enable;
2045 + agp_bridge.cache_flush = smp_flush_cache;
2047 + agp_bridge.cache_flush = flush_cache;
2049 + agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
2050 + agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
2051 + agp_bridge.insert_memory = agp_generic_insert_memory;
2052 + agp_bridge.remove_memory = agp_generic_remove_memory;
2053 + agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
2054 + agp_bridge.free_by_type = agp_generic_free_by_type;
2061 +/* Supported Device Scanning routine */
2063 +static void agp_find_supported_device(void)
2065 + struct pci_dev *dev = NULL;
2066 + u8 cap_ptr = 0x00;
2067 + u32 cap_id, scratch;
2069 + if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) == NULL) {
2070 + agp_bridge.type = NOT_SUPPORTED;
2073 + agp_bridge.dev = dev;
2075 + /* Need to test for I810 here */
2076 +#ifdef AGP_BUILD_INTEL_I810
2077 + if (dev->vendor == PCI_VENDOR_ID_INTEL) {
2078 + struct pci_dev *i810_dev;
2080 + switch (dev->device) {
2081 + case PCI_DEVICE_ID_INTEL_810_0:
2082 + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
2083 + PCI_DEVICE_ID_INTEL_810_1,
2085 + if (i810_dev == NULL) {
2086 + printk("agpgart: Detected an Intel i810, but could not find the secondary device.\n");
2087 + agp_bridge.type = NOT_SUPPORTED;
2090 + printk("agpgart: Detected an Intel i810 Chipset.\n");
2091 + agp_bridge.type = INTEL_I810;
2092 + agp_bridge.intel_i810_setup(i810_dev);
2095 + case PCI_DEVICE_ID_INTEL_810_DC100_0:
2096 + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
2097 + PCI_DEVICE_ID_INTEL_810_DC100_1,
2099 + if (i810_dev == NULL) {
2100 + printk("agpgart: Detected an Intel i810 DC100, but could not find the secondary device.\n");
2101 + agp_bridge.type = NOT_SUPPORTED;
2104 + printk("agpgart: Detected an Intel i810 DC100 Chipset.\n");
2105 + agp_bridge.type = INTEL_I810;
2106 + agp_bridge.intel_i810_setup(i810_dev);
2109 + case PCI_DEVICE_ID_INTEL_810_E_0:
2110 + i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
2111 + PCI_DEVICE_ID_INTEL_810_E_1,
2113 + if (i810_dev == NULL) {
2114 + printk("agpgart: Detected an Intel i810 E, but could not find the secondary device.\n");
2115 + agp_bridge.type = NOT_SUPPORTED;
2118 + printk("agpgart: Detected an Intel i810 E Chipset.\n");
2119 + agp_bridge.type = INTEL_I810;
2120 + agp_bridge.intel_i810_setup(i810_dev);
2128 + pci_read_config_dword(dev, 0x04, &scratch);
2130 + if (!(scratch & 0x00100000)) {
2131 + agp_bridge.type = NOT_SUPPORTED;
2134 + pci_read_config_byte(dev, 0x34, &cap_ptr);
2136 + if (cap_ptr != 0x00) {
2138 + pci_read_config_dword(dev, cap_ptr, &cap_id);
2140 + if ((cap_id & 0xff) != 0x02)
2141 + cap_ptr = (cap_id >> 8) & 0xff;
2143 + while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
2145 + if (cap_ptr == 0x00) {
2146 + agp_bridge.type = NOT_SUPPORTED;
2149 + agp_bridge.capndx = cap_ptr;
2151 + /* Fill in the mode register */
2152 + pci_read_config_dword(agp_bridge.dev,
2153 + agp_bridge.capndx + 4,
2154 + &agp_bridge.mode);
2156 + switch (dev->vendor) {
2157 +#ifdef AGP_BUILD_INTEL_GENERIC
2158 + case PCI_VENDOR_ID_INTEL:
2159 + switch (dev->device) {
2160 + case PCI_DEVICE_ID_INTEL_82443LX_0:
2161 + agp_bridge.type = INTEL_LX;
2162 + printk("agpgart: Detected an Intel 440LX Chipset.\n");
2163 + agp_bridge.intel_generic_setup();
2166 + case PCI_DEVICE_ID_INTEL_82443BX_0:
2167 + agp_bridge.type = INTEL_BX;
2168 + printk("agpgart: Detected an Intel 440BX Chipset.\n");
2169 + agp_bridge.intel_generic_setup();
2172 + case PCI_DEVICE_ID_INTEL_82443GX_0:
2173 + agp_bridge.type = INTEL_GX;
2174 + printk("agpgart: Detected an Intel 440GX Chipset.\n");
2175 + agp_bridge.intel_generic_setup();
2179 + if (agp_try_unsupported != 0) {
2180 + printk("agpgart: Trying generic intel routines for device id: %x\n", dev->device);
2181 + agp_bridge.type = INTEL_GENERIC;
2182 + agp_bridge.intel_generic_setup();
2185 + printk("agpgart: Unsupported intel chipset, you might want to try agp_try_unsupported=1.\n");
2186 + agp_bridge.type = NOT_SUPPORTED;
2193 +#ifdef AGP_BUILD_VIA_GENERIC
2194 + case PCI_VENDOR_ID_VIA:
2195 + switch (dev->device) {
2196 + case PCI_DEVICE_ID_VIA_82C597_0:
2197 + agp_bridge.type = VIA_VP3;
2198 + printk("agpgart: Detected a VIA VP3 Chipset.\n");
2199 + agp_bridge.via_generic_setup();
2202 + case PCI_DEVICE_ID_VIA_82C598_0:
2203 + agp_bridge.type = VIA_MVP3;
2204 + printk("agpgart: Detected a VIA MVP3 Chipset.\n");
2205 + agp_bridge.via_generic_setup();
2208 + case PCI_DEVICE_ID_VIA_82C691_0:
2209 + agp_bridge.type = VIA_APOLLO_PRO;
2210 + printk("agpgart: Detected a VIA Apollo Pro Chipset.\n");
2211 + agp_bridge.via_generic_setup();
2215 + if (agp_try_unsupported != 0) {
2216 + printk("agpgart: Trying generic VIA routines for device id: %x\n", dev->device);
2217 + agp_bridge.type = VIA_GENERIC;
2218 + agp_bridge.via_generic_setup();
2221 + printk("agpgart: Unsupported VIA chipset, you might want to try agp_try_unsupported=1.\n");
2222 + agp_bridge.type = NOT_SUPPORTED;
2229 +#ifdef AGP_BUILD_SIS_GENERIC
2230 + case PCI_VENDOR_ID_SI:
2231 + switch (dev->device) {
2232 + /* ToDo need to find out the specific devices supported */
2234 + if (agp_try_unsupported != 0) {
2235 + printk("agpgart: Trying generic SiS routines for device id: %x\n", dev->device);
2236 + agp_bridge.type = SIS_GENERIC;
2237 + agp_bridge.sis_generic_setup();
2240 + printk("agpgart: Unsupported SiS chipset, you might want to try agp_try_unsupported=1.\n");
2241 + agp_bridge.type = NOT_SUPPORTED;
2248 +#ifdef AGP_BUILD_AMD_IRONGATE
2249 + case PCI_VENDOR_ID_AMD:
2250 + switch (dev->device) {
2251 + case PCI_DEVICE_ID_AMD_IRONGATE_0:
2252 + agp_bridge.type = AMD_IRONGATE;
2253 + printk("agpgart: Detected an AMD Irongate Chipset.\n");
2254 + agp_bridge.amd_irongate_setup();
2258 + if (agp_try_unsupported != 0) {
2259 + printk("agpgart: Trying Amd irongate routines for device id: %x\n", dev->device);
2260 + agp_bridge.type = AMD_GENERIC;
2261 + agp_bridge.amd_irongate_setup();
2264 + printk("agpgart: Unsupported Amd chipset, you might want to try agp_try_unsupported=1.\n");
2265 + agp_bridge.type = NOT_SUPPORTED;
2272 +#ifdef AGP_BUILD_ALI_M1541
2273 + case PCI_VENDOR_ID_AL:
2274 + switch (dev->device) {
2275 + case PCI_DEVICE_ID_AL_M1541_0:
2276 + agp_bridge.type = ALI_M1541;
2277 + printk("agpgart: Detected an ALi M1541 Chipset\n");
2278 + agp_bridge.ali_generic_setup();
2281 + if (agp_try_unsupported != 0) {
2282 + printk("agpgart: Trying ALi generic routines for device id: %x\n", dev->device);
2283 + agp_bridge.type = ALI_GENERIC;
2284 + agp_bridge.ali_generic_setup();
2287 + printk("agpgart: Unsupported ALi chipset, you might want to type agp_try_unsupported=1.\n");
2288 + agp_bridge.type = NOT_SUPPORTED;
2295 + agp_bridge.type = NOT_SUPPORTED;
2300 +struct agp_max_table {
2305 +static struct agp_max_table agp_maxes_table[9] =
2318 +static int agp_find_max(void)
2325 + memory = virt_to_phys(high_memory) / 0x100000;
2328 + while ((memory > agp_maxes_table[index].mem) &&
2333 + t = (memory - agp_maxes_table[index - 1].mem) /
2334 + (agp_maxes_table[index].mem - agp_maxes_table[index - 1].mem);
2336 + result = agp_maxes_table[index - 1].agp +
2337 + (t * (agp_maxes_table[index].agp - agp_maxes_table[index - 1].agp));
2339 + printk("agpgart: Maximum main memory to use for agp memory: %dM\n", result);
2340 + result = (result * 0x100000) / 4096;
2344 +#define AGPGART_VERSION_MAJOR 0
2345 +#define AGPGART_VERSION_MINOR 99
2347 +static agp_version agp_current_version =
2349 + AGPGART_VERSION_MAJOR,
2350 + AGPGART_VERSION_MINOR
2353 +static int agp_backend_initialize(void)
2357 + memset(&agp_bridge, 0, sizeof(struct agp_bridge_data));
2358 + agp_bridge.type = NOT_SUPPORTED;
2359 +#ifdef AGP_BUILD_INTEL_GENERIC
2360 + agp_bridge.intel_generic_setup = intel_generic_setup;
2362 +#ifdef AGP_BUILD_INTEL_I810
2363 + agp_bridge.intel_i810_setup = intel_i810_setup;
2365 +#ifdef AGP_BUILD_VIA_GENERIC
2366 + agp_bridge.via_generic_setup = via_generic_setup;
2368 +#ifdef AGP_BUILD_SIS_GENERIC
2369 + agp_bridge.sis_generic_setup = sis_generic_setup;
2371 +#ifdef AGP_BUILD_AMD_IRONGATE
2372 + agp_bridge.amd_irongate_setup = amd_irongate_setup;
2374 +#ifdef AGP_BUILD_ALI_M1541
2375 + agp_bridge.ali_generic_setup = ali_generic_setup;
2377 + agp_bridge.max_memory_agp = agp_find_max();
2378 + agp_bridge.version = &agp_current_version;
2379 + agp_find_supported_device();
2381 + if (agp_bridge.needs_scratch_page == TRUE) {
2382 + agp_bridge.scratch_page = (unsigned long) agp_alloc_page();
2384 + if ((void *) (agp_bridge.scratch_page) == NULL) {
2385 + printk("agpgart: unable to get memory for scratch page.\n");
2388 + agp_bridge.scratch_page = virt_to_phys((void *) agp_bridge.scratch_page);
2389 + agp_bridge.scratch_page = agp_bridge.mask_memory(agp_bridge.scratch_page, 0);
2391 + if (agp_bridge.type == NOT_SUPPORTED) {
2392 + printk("agpgart: no supported devices found.\n");
2395 + size_value = agp_bridge.fetch_size();
2397 + if (size_value == 0) {
2398 + printk("agpgart: unable to detrimine aperture size.\n");
2401 + if (agp_bridge.create_gatt_table()) {
2402 + printk("agpgart: unable to get memory for graphics translation table.\n");
2405 + agp_bridge.key_list = vmalloc(PAGE_SIZE * 4);
2407 + if (agp_bridge.key_list == NULL) {
2408 + printk("agpgart: error allocating memory for key lists.\n");
2409 + agp_bridge.free_gatt_table();
2412 + memset(agp_bridge.key_list, 0, PAGE_SIZE * 4);
2414 + if (agp_bridge.configure()) {
2415 + printk("agpgart: error configuring host chipset.\n");
2416 + agp_bridge.free_gatt_table();
2417 + vfree(agp_bridge.key_list);
2420 + printk("agpgart: Physical address of the agp aperture: 0x%lx\n", agp_bridge.gart_bus_addr);
2421 + printk("agpgart: Agp aperture is %dM in size.\n", size_value);
2425 +static void agp_backend_cleanup(void)
2427 + agp_bridge.cleanup();
2428 + agp_bridge.free_gatt_table();
2429 + vfree(agp_bridge.key_list);
2431 + if (agp_bridge.needs_scratch_page == TRUE) {
2432 + agp_bridge.scratch_page &= ~(0x00000fff);
2433 + agp_destroy_page((void *) phys_to_virt(agp_bridge.scratch_page));
2437 +extern int agp_frontend_initialize(void);
2438 +extern void agp_frontend_cleanup(void);
2441 +int init_module(void)
2445 + printk("Linux agpgart interface v%d.%d (c) Jeff Hartmann\n",
2446 + AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
2447 + ret_val = agp_backend_initialize();
2449 + if (ret_val != 0) {
2452 + ret_val = agp_frontend_initialize();
2454 + if (ret_val != 0) {
2455 + agp_backend_cleanup();
2461 +void cleanup_module(void)
2463 + agp_frontend_cleanup();
2464 + agp_backend_cleanup();
2468 --- linux/drivers/char/agp/agp_backendP.h.newagpdist Fri Feb 11 14:50:45 2000
2469 +++ linux/drivers/char/agp/agp_backendP.h Fri Feb 11 14:50:45 2000
2472 + * AGPGART module version 0.99
2473 + * Copyright (C) 1999 Jeff Hartmann
2474 + * Copyright (C) 1999 Precision Insight
2475 + * Copyright (C) 1999 Xi Graphics
2477 + * Permission is hereby granted, free of charge, to any person obtaining a
2478 + * copy of this software and associated documentation files (the "Software"),
2479 + * to deal in the Software without restriction, including without limitation
2480 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
2481 + * and/or sell copies of the Software, and to permit persons to whom the
2482 + * Software is furnished to do so, subject to the following conditions:
2484 + * The above copyright notice and this permission notice shall be included
2485 + * in all copies or substantial portions of the Software.
2487 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2488 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2489 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2490 + * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
2491 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2492 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
2493 + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2497 +#ifndef _AGP_BACKEND_PRIV_H
2498 +#define _AGP_BACKEND_PRIV_H 1
2500 +enum aper_size_type {
2507 +typedef struct _gatt_mask {
2508 + unsigned long mask;
2510 + /* totally device specific, for integrated chipsets that
2511 + * might have different types of memory masks. For other
2512 + * devices this will probably be ignored */
2515 +typedef struct _aper_size_info_8 {
2520 +} aper_size_info_8;
2522 +typedef struct _aper_size_info_16 {
2527 +} aper_size_info_16;
2529 +typedef struct _aper_size_info_32 {
2534 +} aper_size_info_32;
2536 +typedef struct _aper_size_info_fixed {
2540 +} aper_size_info_fixed;
2542 +struct agp_bridge_data {
2543 + agp_version *version;
2544 + void *aperture_sizes;
2545 + void *previous_size;
2546 + void *current_size;
2547 + void *dev_private_data;
2548 + struct pci_dev *dev;
2550 + unsigned long *gatt_table;
2551 + unsigned long *gatt_table_real;
2552 + unsigned long scratch_page;
2553 + unsigned long gart_bus_addr;
2554 + unsigned long gatt_bus_addr;
2556 + enum chipset_type type;
2557 + enum aper_size_type size_type;
2559 + atomic_t current_memory_agp;
2560 + atomic_t agp_in_use;
2561 + int max_memory_agp; /* in number of pages */
2562 + int needs_scratch_page;
2563 + int aperture_size_idx;
2564 + int num_aperture_sizes;
2568 + /* Links to driver specific functions */
2570 + int (*fetch_size) (void); /* returns the index into the size table */
2571 + int (*configure) (void);
2572 + void (*agp_enable) (u32);
2573 + void (*cleanup) (void);
2574 + void (*tlb_flush) (agp_memory *);
2575 + unsigned long (*mask_memory) (unsigned long, int);
2576 + void (*cache_flush) (void);
2577 + int (*create_gatt_table) (void);
2578 + int (*free_gatt_table) (void);
2579 + int (*insert_memory) (agp_memory *, off_t, int);
2580 + int (*remove_memory) (agp_memory *, off_t, int);
2581 + agp_memory *(*alloc_by_type) (size_t, int);
2582 + void (*free_by_type) (agp_memory *);
2584 + /* Links to vendor/device specific setup functions */
2585 +#ifdef AGP_BUILD_INTEL_GENERIC
2586 + void (*intel_generic_setup) (void);
2588 +#ifdef AGP_BUILD_INTEL_I810
2589 + void (*intel_i810_setup) (struct pci_dev *);
2591 +#ifdef AGP_BUILD_VIA_GENERIC
2592 + void (*via_generic_setup) (void);
2594 +#ifdef AGP_BUILD_SIS_GENERIC
2595 + void (*sis_generic_setup) (void);
2597 +#ifdef AGP_BUILD_AMD_IRONGATE
2598 + void (*amd_irongate_setup) (void);
2600 +#ifdef AGP_BUILD_ALI_M1541
2601 + void (*ali_generic_setup) (void);
2605 +#define OUTREG32(mmap, addr, val) *(volatile u32 *)(mmap + (addr)) = (val)
2606 +#define OUTREG16(mmap, addr, val) *(volatile u16 *)(mmap + (addr)) = (val)
2607 +#define OUTREG8 (mmap, addr, val) *(volatile u8 *) (mmap + (addr)) = (val)
2609 +#define INREG32(mmap, addr) *(volatile u32 *)(mmap + (addr))
2610 +#define INREG16(mmap, addr) *(volatile u16 *)(mmap + (addr))
2611 +#define INREG8 (mmap, addr) *(volatile u8 *) (mmap + (addr))
2614 +#define min(a,b) (((a)<(b))?(a):(b))
2617 +#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge.scratch_page)
2619 +#ifndef PCI_DEVICE_ID_VIA_82C691_0
2620 +#define PCI_DEVICE_ID_VIA_82C691_0 0x0691
2622 +#ifndef PCI_DEVICE_ID_VIA_82C691_1
2623 +#define PCI_DEVICE_ID_VIA_82C691_1 0x8691
2625 +#ifndef PCI_DEVICE_ID_INTEL_810_0
2626 +#define PCI_DEVICE_ID_INTEL_810_0 0x7120
2628 +#ifndef PCI_DEVICE_ID_INTEL_810_DC100_0
2629 +#define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122
2631 +#ifndef PCI_DEVICE_ID_INTEL_810_E_0
2632 +#define PCI_DEVICE_ID_INTEL_810_E_0 0x7124
2634 +#ifndef PCI_DEVICE_ID_INTEL_82443GX_0
2635 +#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
2637 +#ifndef PCI_DEVICE_ID_INTEL_810_1
2638 +#define PCI_DEVICE_ID_INTEL_810_1 0x7121
2640 +#ifndef PCI_DEVICE_ID_INTEL_810_DC100_1
2641 +#define PCI_DEVICE_ID_INTEL_810_DC100_1 0x7123
2643 +#ifndef PCI_DEVICE_ID_INTEL_810_E_1
2644 +#define PCI_DEVICE_ID_INTEL_810_E_1 0x7125
2646 +#ifndef PCI_DEVICE_ID_INTEL_82443GX_1
2647 +#define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1
2649 +#ifndef PCI_DEVICE_ID_AMD_IRONGATE_0
2650 +#define PCI_DEVICE_ID_AMD_IRONGATE_0 0x7006
2652 +#ifndef PCI_VENDOR_ID_AL
2653 +#define PCI_VENDOR_ID_AL 0x10b9
2655 +#ifndef PCI_DEVICE_ID_AL_M1541_0
2656 +#define PCI_DEVICE_ID_AL_M1541_0 0x1541
2659 +/* intel register */
2660 +#define INTEL_APBASE 0x10
2661 +#define INTEL_APSIZE 0xb4
2662 +#define INTEL_ATTBASE 0xb8
2663 +#define INTEL_AGPCTRL 0xb0
2664 +#define INTEL_NBXCFG 0x50
2665 +#define INTEL_ERRSTS 0x91
2667 +/* intel i810 registers */
2668 +#define I810_GMADDR 0x10
2669 +#define I810_MMADDR 0x14
2670 +#define I810_PTE_BASE 0x10000
2671 +#define I810_PTE_MAIN_UNCACHED 0x00000000
2672 +#define I810_PTE_LOCAL 0x00000002
2673 +#define I810_PTE_VALID 0x00000001
2674 +#define I810_SMRAM_MISCC 0x70
2675 +#define I810_GFX_MEM_WIN_SIZE 0x00010000
2676 +#define I810_GFX_MEM_WIN_32M 0x00010000
2677 +#define I810_GMS 0x000000c0
2678 +#define I810_GMS_DISABLE 0x00000000
2679 +#define I810_PGETBL_CTL 0x2020
2680 +#define I810_PGETBL_ENABLED 0x00000001
2681 +#define I810_DRAM_CTL 0x3000
2682 +#define I810_DRAM_ROW_0 0x00000001
2683 +#define I810_DRAM_ROW_0_SDRAM 0x00000001
2686 +#define VIA_APBASE 0x10
2687 +#define VIA_GARTCTRL 0x80
2688 +#define VIA_APSIZE 0x84
2689 +#define VIA_ATTBASE 0x88
2691 +/* SiS registers */
2692 +#define SIS_APBASE 0x10
2693 +#define SIS_ATTBASE 0x90
2694 +#define SIS_APSIZE 0x94
2695 +#define SIS_TLBCNTRL 0x97
2696 +#define SIS_TLBFLUSH 0x98
2698 +/* AMD registers */
2699 +#define AMD_APBASE 0x10
2700 +#define AMD_MMBASE 0x14
2701 +#define AMD_APSIZE 0xac
2702 +#define AMD_MODECNTL 0xb0
2703 +#define AMD_GARTENABLE 0x02 /* In mmio region (16-bit register) */
2704 +#define AMD_ATTBASE 0x04 /* In mmio region (32-bit register) */
2705 +#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
2706 +#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
2708 +/* ALi registers */
2709 +#define ALI_APBASE 0x10
2710 +#define ALI_AGPCTRL 0xb8
2711 +#define ALI_ATTBASE 0xbc
2712 +#define ALI_TLBCTRL 0xc0
2714 +#endif /* _AGP_BACKEND_PRIV_H */
2715 --- linux/drivers/char/agp/agpgart_fe.c.newagpdist Fri Feb 11 14:50:45 2000
2716 +++ linux/drivers/char/agp/agpgart_fe.c Fri Feb 11 14:50:45 2000
2719 + * AGPGART module frontend version 0.99
2720 + * Copyright (C) 1999 Jeff Hartmann
2721 + * Copyright (C) 1999 Precision Insight
2722 + * Copyright (C) 1999 Xi Graphics
2724 + * Permission is hereby granted, free of charge, to any person obtaining a
2725 + * copy of this software and associated documentation files (the "Software"),
2726 + * to deal in the Software without restriction, including without limitation
2727 + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
2728 + * and/or sell copies of the Software, and to permit persons to whom the
2729 + * Software is furnished to do so, subject to the following conditions:
2731 + * The above copyright notice and this permission notice shall be included
2732 + * in all copies or substantial portions of the Software.
2734 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2735 + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2736 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2737 + * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
2738 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2739 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
2740 + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2744 +#define __NO_VERSION__
2745 +#include <linux/config.h>
2746 +#include <linux/version.h>
2747 +#include <linux/types.h>
2748 +#include <linux/kernel.h>
2749 +#include <linux/module.h>
2750 +#include <linux/sched.h>
2751 +#include <linux/mm.h>
2752 +#include <linux/string.h>
2753 +#include <linux/errno.h>
2754 +#include <linux/malloc.h>
2755 +#include <linux/vmalloc.h>
2756 +#include <linux/pci.h>
2757 +#include <linux/init.h>
2758 +#include <linux/pagemap.h>
2759 +#include <linux/miscdevice.h>
2760 +#include <linux/agp_backend.h>
2761 +#include <linux/agpgart.h>
2762 +#include <asm/system.h>
2763 +#include <asm/uaccess.h>
2764 +#include <asm/system.h>
2765 +#include <asm/io.h>
2766 +#include <asm/page.h>
2767 +#include <asm/mman.h>
2769 +static struct agp_front_data agp_fe;
2771 +static agp_memory *agp_find_mem_by_key(int key)
2775 + if (agp_fe.current_controller == NULL) {
2778 + curr = agp_fe.current_controller->pool;
2780 + while (curr != NULL) {
2781 + if (curr->key == key) {
2784 + curr = curr->next;
2790 +static void agp_remove_from_pool(agp_memory * temp)
2795 + /* Check to see if this is even in the memory pool */
2797 + if (agp_find_mem_by_key(temp->key) != NULL) {
2798 + next = temp->next;
2799 + prev = temp->prev;
2801 + if (prev != NULL) {
2802 + prev->next = next;
2803 + if (next != NULL) {
2804 + next->prev = prev;
2807 + /* This is the first item on the list */
2808 + if (next != NULL) {
2809 + next->prev = NULL;
2811 + agp_fe.current_controller->pool = next;
2817 + * Routines for managing each client's segment list -
2818 + * These routines handle adding and removing segments
2819 + * to each auth'ed client.
2822 +static agp_segment_priv *agp_find_seg_in_client(const agp_client * client,
2823 + unsigned long offset,
2824 + int size, pgprot_t page_prot)
2826 + agp_segment_priv *seg;
2827 + int num_segments, pg_start, pg_count, i;
2829 + pg_start = offset / 4096;
2830 + pg_count = size / 4096;
2831 + seg = *(client->segments);
2832 + num_segments = client->num_segments;
2834 + for (i = 0; i < client->num_segments; i++) {
2835 + if ((seg[i].pg_start == pg_start) &&
2836 + (seg[i].pg_count == pg_count) &&
2837 + (pgprot_val(seg[i].prot) == pgprot_val(page_prot))) {
2845 +static void agp_remove_seg_from_client(agp_client * client)
2847 + if (client->segments != NULL) {
2848 + if (*(client->segments) != NULL) {
2849 + kfree(*(client->segments));
2851 + kfree(client->segments);
2855 +static void agp_add_seg_to_client(agp_client * client,
2856 + agp_segment_priv ** seg, int num_segments)
2858 + agp_segment_priv **prev_seg;
2860 + prev_seg = client->segments;
2862 + if (prev_seg != NULL) {
2863 + agp_remove_seg_from_client(client);
2865 + client->num_segments = num_segments;
2866 + client->segments = seg;
2869 +/* Originally taken from linux/mm/mmap.c from the array
2871 + * The original really should be exported to modules, or
2872 + * some routine which does the conversion for you
2875 +static const pgprot_t my_protect_map[16] =
2877 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
2878 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
2881 +static pgprot_t agp_convert_mmap_flags(int prot)
2883 +#define _trans(x,bit1,bit2) \
2884 +((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
2886 + unsigned long prot_bits;
2889 + prot_bits = _trans(prot, PROT_READ, VM_READ) |
2890 + _trans(prot, PROT_WRITE, VM_WRITE) |
2891 + _trans(prot, PROT_EXEC, VM_EXEC);
2893 + prot_bits |= VM_SHARED;
2895 + temp = my_protect_map[prot_bits & 0x0000000f];
2900 +static int agp_create_segment(agp_client * client, agp_region * region)
2902 + agp_segment_priv **ret_seg;
2903 + agp_segment_priv *seg;
2904 + agp_segment *user_seg;
2907 + seg = kmalloc((sizeof(agp_segment_priv) * region->seg_count), GFP_KERNEL);
2908 + if (seg == NULL) {
2909 + kfree(region->seg_list);
2912 + memset(seg, 0, (sizeof(agp_segment_priv) * region->seg_count));
2913 + user_seg = region->seg_list;
2915 + for (i = 0; i < region->seg_count; i++) {
2916 + seg[i].pg_start = user_seg[i].pg_start;
2917 + seg[i].pg_count = user_seg[i].pg_count;
2918 + seg[i].prot = agp_convert_mmap_flags(user_seg[i].prot);
2920 + ret_seg = kmalloc(sizeof(void *), GFP_KERNEL);
2921 + if (ret_seg == NULL) {
2922 + kfree(region->seg_list);
2927 + kfree(region->seg_list);
2928 + agp_add_seg_to_client(client, ret_seg, region->seg_count);
2932 +/* End - Routines for managing each client's segment list */
2934 +/* This function must only be called when current_controller != NULL */
2935 +static void agp_insert_into_pool(agp_memory * temp)
2939 + prev = agp_fe.current_controller->pool;
2941 + if (prev != NULL) {
2942 + prev->prev = temp;
2943 + temp->next = prev;
2945 + agp_fe.current_controller->pool = temp;
2949 +/* File private list routines */
2951 +agp_file_private *agp_find_private(pid_t pid)
2953 + agp_file_private *curr;
2955 + curr = agp_fe.file_priv_list;
2957 + while (curr != NULL) {
2958 + if (curr->my_pid == pid) {
2961 + curr = curr->next;
2967 +void agp_insert_file_private(agp_file_private * priv)
2969 + agp_file_private *prev;
2971 + prev = agp_fe.file_priv_list;
2973 + if (prev != NULL) {
2974 + prev->prev = priv;
2976 + priv->next = prev;
2977 + agp_fe.file_priv_list = priv;
2980 +void agp_remove_file_private(agp_file_private * priv)
2982 + agp_file_private *next;
2983 + agp_file_private *prev;
2985 + next = priv->next;
2986 + prev = priv->prev;
2988 + if (prev != NULL) {
2989 + prev->next = next;
2991 + if (next != NULL) {
2992 + next->prev = prev;
2995 + if (next != NULL) {
2996 + next->prev = NULL;
2998 + agp_fe.file_priv_list = next;
3002 +/* End - File flag list routines */
3005 + * Wrappers for agp_free_memory & agp_allocate_memory
3006 + * These make sure that internal lists are kept updated.
3008 +static void agp_free_memory_wrap(agp_memory * memory)
3010 + agp_remove_from_pool(memory);
3011 + agp_free_memory(memory);
3014 +static agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
3016 + agp_memory *memory;
3018 + memory = agp_allocate_memory(pg_count, type);
3020 + if (memory == NULL) {
3023 + agp_insert_into_pool(memory);
3027 +/* Routines for managing the list of controllers -
3028 + * These routines manage the current controller, and the list of
3032 +static agp_controller *agp_find_controller_by_pid(pid_t id)
3034 + agp_controller *controller;
3036 + controller = agp_fe.controllers;
3038 + while (controller != NULL) {
3039 + if (controller->pid == id) {
3040 + return controller;
3042 + controller = controller->next;
3048 +static agp_controller *agp_create_controller(pid_t id)
3050 + agp_controller *controller;
3052 + controller = kmalloc(sizeof(agp_controller), GFP_KERNEL);
3054 + if (controller == NULL) {
3057 + memset(controller, 0, sizeof(agp_controller));
3058 + controller->pid = id;
3060 + return controller;
3063 +static int agp_insert_controller(agp_controller * controller)
3065 + agp_controller *prev_controller;
3067 + prev_controller = agp_fe.controllers;
3068 + controller->next = prev_controller;
3070 + if (prev_controller != NULL) {
3071 + prev_controller->prev = controller;
3073 + agp_fe.controllers = controller;
3078 +static void agp_remove_all_clients(agp_controller * controller)
3080 + agp_client *client;
3083 + client = controller->clients;
3086 + agp_file_private *priv;
3089 + agp_remove_seg_from_client(temp);
3090 + priv = agp_find_private(temp->pid);
3092 + if (priv != NULL) {
3093 + clear_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3094 + clear_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
3096 + client = client->next;
3101 +static void agp_remove_all_memory(agp_controller * controller)
3103 + agp_memory *memory;
3106 + memory = controller->pool;
3110 + memory = memory->next;
3111 + agp_free_memory_wrap(temp);
3115 +static int agp_remove_controller(agp_controller * controller)
3117 + agp_controller *prev_controller;
3118 + agp_controller *next_controller;
3120 + prev_controller = controller->prev;
3121 + next_controller = controller->next;
3123 + if (prev_controller != NULL) {
3124 + prev_controller->next = next_controller;
3125 + if (next_controller != NULL) {
3126 + next_controller->prev = prev_controller;
3129 + if (next_controller != NULL) {
3130 + next_controller->prev = NULL;
3132 + agp_fe.controllers = next_controller;
3135 + agp_remove_all_memory(controller);
3136 + agp_remove_all_clients(controller);
3138 + if (agp_fe.current_controller == controller) {
3139 + agp_fe.current_controller = NULL;
3140 + agp_fe.backend_acquired = FALSE;
3141 + agp_backend_release();
3143 + kfree(controller);
3147 +static void agp_controller_make_current(agp_controller * controller)
3149 + agp_client *clients;
3151 + clients = controller->clients;
3153 + while (clients != NULL) {
3154 + agp_file_private *priv;
3156 + priv = agp_find_private(clients->pid);
3158 + if (priv != NULL) {
3159 + set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3160 + set_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
3162 + clients = clients->next;
3165 + agp_fe.current_controller = controller;
3168 +static void agp_controller_release_current(agp_controller * controller,
3169 + agp_file_private * controller_priv)
3171 + agp_client *clients;
3173 + clear_bit(AGP_FF_IS_VALID, &(controller_priv->access_flags));
3174 + clients = controller->clients;
3176 + while (clients != NULL) {
3177 + agp_file_private *priv;
3179 + priv = agp_find_private(clients->pid);
3181 + if (priv != NULL) {
3182 + clear_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3184 + clients = clients->next;
3187 + agp_fe.current_controller = NULL;
3188 + agp_fe.used_by_controller = FALSE;
3189 + agp_backend_release();
3193 + * Routines for managing client lists -
3194 + * These routines are for managing the list of auth'ed clients.
3197 +static agp_client *agp_find_client_in_controller(agp_controller * controller,
3200 + agp_client *client;
3202 + if (controller == NULL) {
3205 + client = controller->clients;
3207 + while (client != NULL) {
3208 + if (client->pid == id) {
3211 + client = client->next;
3217 +static agp_controller *agp_find_controller_for_client(pid_t id)
3219 + agp_controller *controller;
3221 + controller = agp_fe.controllers;
3223 + while (controller != NULL) {
3224 + if ((agp_find_client_in_controller(controller, id)) != NULL) {
3225 + return controller;
3227 + controller = controller->next;
3233 +static agp_client *agp_find_client_by_pid(pid_t id)
3237 + if (agp_fe.current_controller == NULL) {
3240 + temp = agp_find_client_in_controller(agp_fe.current_controller, id);
3244 +static void agp_insert_client(agp_client * client)
3246 + agp_client *prev_client;
3248 + prev_client = agp_fe.current_controller->clients;
3249 + client->next = prev_client;
3251 + if (prev_client != NULL) {
3252 + prev_client->prev = client;
3254 + agp_fe.current_controller->clients = client;
3255 + agp_fe.current_controller->num_clients++;
3258 +static agp_client *agp_create_client(pid_t id)
3260 + agp_client *new_client;
3262 + new_client = kmalloc(sizeof(agp_client), GFP_KERNEL);
3264 + if (new_client == NULL) {
3267 + memset(new_client, 0, sizeof(agp_client));
3268 + new_client->pid = id;
3269 + agp_insert_client(new_client);
3270 + return new_client;
3273 +static int agp_remove_client(pid_t id)
3275 + agp_client *client;
3276 + agp_client *prev_client;
3277 + agp_client *next_client;
3278 + agp_controller *controller;
3280 + controller = agp_find_controller_for_client(id);
3282 + if (controller == NULL) {
3285 + client = agp_find_client_in_controller(controller, id);
3287 + if (client == NULL) {
3290 + prev_client = client->prev;
3291 + next_client = client->next;
3293 + if (prev_client != NULL) {
3294 + prev_client->next = next_client;
3295 + if (next_client != NULL) {
3296 + next_client->prev = prev_client;
3299 + if (next_client != NULL) {
3300 + next_client->prev = NULL;
3302 + controller->clients = next_client;
3305 + controller->num_clients--;
3306 + agp_remove_seg_from_client(client);
3311 +/* End - Routines for managing client lists */
3313 +/* File Operations */
3315 +static int agp_mmap(struct file *file, struct vm_area_struct *vma)
3319 + unsigned long offset;
3320 + agp_client *client;
3321 + agp_file_private *priv = (agp_file_private *) file->private_data;
3322 + agp_kern_info kerninfo;
3326 + if (agp_fe.backend_acquired != TRUE) {
3330 + if (!(test_bit(AGP_FF_IS_VALID, &(priv->access_flags)))) {
3334 + agp_copy_info(&kerninfo);
3335 + size = vma->vm_end - vma->vm_start;
3336 + current_size = kerninfo.aper_size;
3337 + current_size = current_size * 0x100000;
3338 + offset = vma->vm_offset;
3340 + if (test_bit(AGP_FF_IS_CLIENT, &(priv->access_flags))) {
3341 + if ((size + offset) > current_size) {
3345 + client = agp_find_client_by_pid(current->pid);
3347 + if (client == NULL) {
3351 + if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot)) {
3355 + if (remap_page_range(vma->vm_start, (kerninfo.aper_base + offset),
3356 + size, vma->vm_page_prot)) {
3363 + if (test_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags))) {
3364 + if (size != current_size) {
3368 + if (remap_page_range(vma->vm_start, kerninfo.aper_base,
3369 + size, vma->vm_page_prot)) {
3380 +static int agp_release(struct inode *inode, struct file *file)
3382 + agp_file_private *priv = (agp_file_private *) file->private_data;
3386 + if (test_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags))) {
3387 + agp_controller *controller;
3389 + controller = agp_find_controller_by_pid(priv->my_pid);
3391 + if (controller != NULL) {
3392 + if (controller == agp_fe.current_controller) {
3393 + agp_controller_release_current(controller, priv);
3395 + agp_remove_controller(controller);
3398 + if (test_bit(AGP_FF_IS_CLIENT, &(priv->access_flags))) {
3399 + agp_remove_client(priv->my_pid);
3401 + agp_remove_file_private(priv);
3403 + MOD_DEC_USE_COUNT;
3408 +static int agp_open(struct inode *inode, struct file *file)
3410 + int minor = MINOR(inode->i_rdev);
3411 + agp_file_private *priv;
3412 + agp_client *client;
3416 + if (minor != AGPGART_MINOR) {
3420 + priv = kmalloc(sizeof(agp_file_private), GFP_KERNEL);
3422 + if (priv == NULL) {
3426 + memset(priv, 0, sizeof(agp_file_private));
3427 + set_bit(AGP_FF_ALLOW_CLIENT, &(priv->access_flags));
3428 + priv->my_pid = current->pid;
3430 + if ((current->uid == 0) || (current->suid == 0)) {
3431 + /* Root priv, can be controller */
3432 + set_bit(AGP_FF_ALLOW_CONTROLLER, &(priv->access_flags));
3434 + client = agp_find_client_by_pid(current->pid);
3436 + if (client != NULL) {
3437 + set_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
3438 + set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3440 + file->private_data = (void *) priv;
3441 + agp_insert_file_private(priv);
3442 + MOD_INC_USE_COUNT;
3448 +static long long agp_lseek(struct file *file, long long offset, int origin)
3453 +static ssize_t agp_read(struct file *file, char *buf,
3454 + size_t count, loff_t * ppos)
3459 +static ssize_t agp_write(struct file *file, const char *buf,
3460 + size_t count, loff_t * ppos)
3465 +static int agpioc_info_wrap(agp_file_private * priv, unsigned long arg)
3467 + agp_info userinfo;
3468 + agp_kern_info kerninfo;
3470 + agp_copy_info(&kerninfo);
3472 + userinfo.version.major = kerninfo.version.major;
3473 + userinfo.version.minor = kerninfo.version.minor;
3474 + userinfo.bridge_id = kerninfo.device->vendor | (kerninfo.device->device << 16);
3475 + userinfo.agp_mode = kerninfo.mode;
3476 + userinfo.aper_base = kerninfo.aper_base;
3477 + userinfo.aper_size = kerninfo.aper_size;
3478 + userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
3479 + userinfo.pg_used = kerninfo.current_memory;
3481 + if (copy_to_user((void *) arg, &userinfo, sizeof(agp_info))) {
3487 +static int agpioc_acquire_wrap(agp_file_private * priv, unsigned long arg)
3489 + agp_controller *controller;
3490 + if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &(priv->access_flags)))) {
3493 + if (agp_fe.current_controller != NULL) {
3496 + if ((agp_backend_acquire()) == 0) {
3497 + agp_fe.backend_acquired = TRUE;
3502 + controller = agp_find_controller_by_pid(priv->my_pid);
3504 + if (controller != NULL) {
3505 + agp_controller_make_current(controller);
3507 + controller = agp_create_controller(priv->my_pid);
3509 + if (controller == NULL) {
3510 + agp_fe.backend_acquired = FALSE;
3511 + agp_backend_release();
3514 + agp_insert_controller(controller);
3515 + agp_controller_make_current(controller);
3518 + set_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags));
3519 + set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3523 +static int agpioc_release_wrap(agp_file_private * priv, unsigned long arg)
3525 + agp_controller_release_current(agp_fe.current_controller, priv);
3529 +static int agpioc_setup_wrap(agp_file_private * priv, unsigned long arg)
3533 + if (copy_from_user(&mode, (void *) arg, sizeof(agp_setup))) {
3536 + agp_enable(mode.agp_mode);
3540 +static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg)
3542 + agp_region reserve;
3543 + agp_client *client;
3544 + agp_file_private *client_priv;
3547 + if (copy_from_user(&reserve, (void *) arg, sizeof(agp_region))) {
3550 + client = agp_find_client_by_pid(reserve.pid);
3552 + if (reserve.seg_count == 0) {
3553 + /* remove a client */
3554 + client_priv = agp_find_private(reserve.pid);
3556 + if (client_priv != NULL) {
3557 + set_bit(AGP_FF_IS_CLIENT, &(client_priv->access_flags));
3558 + set_bit(AGP_FF_IS_VALID, &(client_priv->access_flags));
3560 + if (client == NULL) {
3561 + /* client is already removed */
3564 + return agp_remove_client(reserve.pid);
3566 + agp_segment *segment;
3568 + segment = kmalloc((sizeof(agp_segment) * reserve.seg_count), GFP_KERNEL);
3570 + if (segment == NULL) {
3573 + if (copy_from_user(segment, (void *) reserve.seg_list, GFP_KERNEL)) {
3577 + reserve.seg_list = segment;
3579 + if (client == NULL) {
3580 + /* Create the client and add the segment */
3581 + client = agp_create_client(reserve.pid);
3583 + if (client == NULL) {
3587 + client_priv = agp_find_private(reserve.pid);
3589 + if (client_priv != NULL) {
3590 + set_bit(AGP_FF_IS_CLIENT, &(client_priv->access_flags));
3591 + set_bit(AGP_FF_IS_VALID, &(client_priv->access_flags));
3593 + return agp_create_segment(client, &reserve);
3595 + return agp_create_segment(client, &reserve);
3598 + /* Will never really happen */
3602 +static int agpioc_protect_wrap(agp_file_private * priv, unsigned long arg)
3604 + /* This function is not currently implemented */
3608 +static int agpioc_allocate_wrap(agp_file_private * priv, unsigned long arg)
3610 + agp_memory *memory;
3611 + agp_allocate alloc;
3613 + if (copy_from_user(&alloc, (void *) arg, sizeof(agp_allocate))) {
3616 + memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
3618 + if (memory == NULL) {
3621 + alloc.key = memory->key;
3623 + if (copy_to_user((void *) arg, &alloc, sizeof(agp_allocate))) {
3624 + agp_free_memory_wrap(memory);
3630 +static int agpioc_deallocate_wrap(agp_file_private * priv, unsigned long arg)
3632 + agp_memory *memory;
3634 + memory = agp_find_mem_by_key((int) arg);
3636 + if (memory == NULL) {
3639 + agp_free_memory_wrap(memory);
3643 +static int agpioc_bind_wrap(agp_file_private * priv, unsigned long arg)
3645 + agp_bind bind_info;
3646 + agp_memory *memory;
3648 + if (copy_from_user(&bind_info, (void *) arg, sizeof(agp_bind))) {
3651 + memory = agp_find_mem_by_key(bind_info.key);
3653 + if (memory == NULL) {
3656 + return agp_bind_memory(memory, bind_info.pg_start);
3659 +static int agpioc_unbind_wrap(agp_file_private * priv, unsigned long arg)
3661 + agp_memory *memory;
3662 + agp_unbind unbind;
3664 + if (copy_from_user(&unbind, (void *) arg, sizeof(agp_unbind))) {
3667 + memory = agp_find_mem_by_key(unbind.key);
3669 + if (memory == NULL) {
3672 + return agp_unbind_memory(memory);
3675 +static int agp_ioctl(struct inode *inode, struct file *file,
3676 + unsigned int cmd, unsigned long arg)
3678 + agp_file_private *curr_priv = (agp_file_private *) file->private_data;
3683 + if ((agp_fe.current_controller == NULL) &&
3684 + (cmd != AGPIOC_ACQUIRE)) {
3687 + if ((agp_fe.backend_acquired != TRUE) &&
3688 + (cmd != AGPIOC_ACQUIRE)) {
3691 + if (cmd != AGPIOC_ACQUIRE) {
3692 + if (!(test_bit(AGP_FF_IS_CONTROLLER, &(curr_priv->access_flags)))) {
3695 + /* Use the original pid of the controller, in case it's threaded */
3697 + if (agp_fe.current_controller->pid != curr_priv->my_pid) {
3704 + ret_val = agpioc_info_wrap(curr_priv, arg);
3708 + case AGPIOC_ACQUIRE:
3710 + ret_val = agpioc_acquire_wrap(curr_priv, arg);
3714 + case AGPIOC_RELEASE:
3716 + ret_val = agpioc_release_wrap(curr_priv, arg);
3720 + case AGPIOC_SETUP:
3722 + ret_val = agpioc_setup_wrap(curr_priv, arg);
3726 + case AGPIOC_RESERVE:
3728 + ret_val = agpioc_reserve_wrap(curr_priv, arg);
3732 + case AGPIOC_PROTECT:
3734 + ret_val = agpioc_protect_wrap(curr_priv, arg);
3738 + case AGPIOC_ALLOCATE:
3740 + ret_val = agpioc_allocate_wrap(curr_priv, arg);
3744 + case AGPIOC_DEALLOCATE:
3746 + ret_val = agpioc_deallocate_wrap(curr_priv, arg);
3752 + ret_val = agpioc_bind_wrap(curr_priv, arg);
3756 + case AGPIOC_UNBIND:
3758 + ret_val = agpioc_unbind_wrap(curr_priv, arg);
3768 +static struct file_operations agp_fops =
3782 +static struct miscdevice agp_miscdev =
3789 +int agp_frontend_initialize(void)
3791 + memset(&agp_fe, 0, sizeof(struct agp_front_data));
3794 + if (misc_register(&agp_miscdev)) {
3795 + printk("agpgart: unable to get minor: %d\n", AGPGART_MINOR);
3801 +void agp_frontend_cleanup(void)
3805 --- linux/drivers/char/Config.in.newagpdist Tue Jan 4 13:12:14 2000
3806 +++ linux/drivers/char/Config.in Fri Feb 11 14:50:45 2000
3808 bool ' Support IEEE1284 status readback' CONFIG_PRINTER_READBACK
3813 bool 'Mouse Support (not serial mice)' CONFIG_MOUSE
3814 if [ "$CONFIG_MOUSE" = "y" ]; then
3815 mainmenu_option next_comment
3816 @@ -116,6 +116,18 @@
3817 bool 'Tadpole ANA H8 Support' CONFIG_H8
3820 +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
3821 + dep_tristate '/dev/agpgart (AGP Support) (EXPERIMENTAL)' CONFIG_AGP m
3822 + if [ "$CONFIG_AGP" = "m" ]; then
3823 + bool ' Intel 440LX/BX/GX support' CONFIG_AGP_INTEL
3824 + bool ' Intel I810/I810 DC100/I810e support' CONFIG_AGP_I810
3825 + bool ' VIA VP3/MVP3/Apollo Pro support' CONFIG_AGP_VIA
3826 + bool ' AMD Irongate support' CONFIG_AGP_AMD
3827 + bool ' Generic SiS support' CONFIG_AGP_SIS
3828 + bool ' ALI M1541 support' CONFIG_AGP_ALI
3832 mainmenu_option next_comment
3833 comment 'Video For Linux'
3835 --- linux/drivers/char/Makefile.newagpdist Fri Feb 11 14:49:48 2000
3836 +++ linux/drivers/char/Makefile Fri Feb 11 14:50:45 2000
3837 @@ -352,6 +352,11 @@
3841 +ifeq ($(CONFIG_AGP), m)
3842 + ALL_SUB_DIRS += agp
3843 + MOD_SUB_DIRS += agp
3846 ifeq ($(CONFIG_VIDEO_DEV),y)
3847 LX_OBJS += videodev.o
3849 --- linux/arch/i386/mm/ioremap.c.newagpdist Mon Aug 9 15:04:38 1999
3850 +++ linux/arch/i386/mm/ioremap.c Fri Feb 11 14:50:45 2000
3851 @@ -110,7 +110,18 @@
3852 * Don't allow anybody to remap normal RAM that we're using..
3854 if (phys_addr < virt_to_phys(high_memory))
3857 + char *temp_addr, *temp_end;
3860 + temp_addr = __va(phys_addr);
3861 + temp_end = temp_addr + (size - 1);
3863 + for(i = MAP_NR(temp_addr); i < MAP_NR(temp_end); i++) {
3864 + if(!PageReserved(mem_map + i))
3870 * Mappings have to be page-aligned
3871 --- linux/Documentation/Configure.help.newagpdist Fri Feb 11 14:49:49 2000
3872 +++ linux/Documentation/Configure.help Fri Feb 11 14:50:45 2000
3873 @@ -9430,6 +9430,20 @@
3874 sampling), then say Y here, and read Documentation/rtc.txt for
3879 + This provides a kernel interface (/dev/agpgart) for programming AGP
3880 + transfers on motherboards that support them. Primarily, this is used
3881 + for hardware-accelerated 3d graphics, though any other AGP device
3882 + could take advantage of it.
3884 + If you have a 3d-capable AGP video card say 'M' or 'Y' here.
3885 + Otherwise, say 'N'.
3887 + You will also have to indicate support for your specific chipset.
3888 + Consult the output of lspci, your motherboard manual, or the inside
3889 + of your computer if unsure what to choose. Multiple selections are ok.
3891 Tadpole ANA H8 Support
3893 The Hitachi H8/337 is a microcontroller used to deal with the power