Commit 8e68fd15 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-dj.bkbits.net/agpgart

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 08b6784d 80a94d01
config AGP config AGP
tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU
default AGP_GART if GART_IOMMU default y if GART_IOMMU
---help--- ---help---
AGP (Accelerated Graphics Port) is a bus system mainly used to AGP (Accelerated Graphics Port) is a bus system mainly used to
connect graphics cards to the rest of the system. connect graphics cards to the rest of the system.
...@@ -25,54 +25,66 @@ config AGP ...@@ -25,54 +25,66 @@ config AGP
a module, say M here and read <file:Documentation/modules.txt>. The a module, say M here and read <file:Documentation/modules.txt>. The
module will be called agpgart. module will be called agpgart.
config AGP_GART config AGP_ALI
bool "/dev/agpgart (AGP Support)" tristate "ALI chipset support"
depends on GART_IOMMU depends on AGP && X86 && !X86_64
---help---
config AGP_INTEL
tristate "Intel 440LX/BX/GX, I8xx and E7x05 support"
depends on AGP && !X86_64
help
This option gives you AGP support for the GLX component of the This option gives you AGP support for the GLX component of the
XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860 XFree86 4.x on the following ALi chipsets. The supported chipsets
E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G, include M1541, M1621, M1631, M1632, M1641,M1647,and M1651.
852GM, 855GM and 865G integrated graphics chipsets. For the ALi-chipset question, ALi suggests you refer to
<http://www.ali.com.tw/eng/support/index.shtml>.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to The M1541 chipset can do AGP 1x and 2x, but note that there is an
use GLX or DRI, or if you have any Intel integrated graphics acknowledged incompatibility with Matrox G200 cards. Due to
chipsets. If unsure, say Y. timing issues, this chipset cannot do AGP 2x with the G200.
This is a hardware limitation. AGP 1x seems to be fine, though.
#config AGP_I810 You should say Y here if you use XFree86 3.3.6 or 4.x and want to
# tristate "Intel I810/I815/I830M (on-board) support" use GLX or DRI. If unsure, say N.
# depends on AGP && !X86_64
# help
# This option gives you AGP support for the Xserver on the Intel 810
# 815 and 830m chipset boards for their on-board integrated graphics. This
# is required to do any useful video modes with these boards.
config AGP_VIA config AGP_AMD
tristate "VIA chipset support" tristate "AMD Irongate, 761, and 762 chipset support"
depends on AGP && !X86_64 depends on AGP && X86 && !X86_64
help help
This option gives you AGP support for the GLX component of the This option gives you AGP support for the GLX component of the
XFree86 4.x on VIA MPV3/Apollo Pro chipsets. XFree86 4.x on AMD Irongate, 761, and 762 chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N. use GLX or DRI. If unsure, say N.
config AGP_AMD config AGP_AMD_8151
tristate "AMD Irongate, 761, and 762 support" tristate "AMD 8151 chipset support"
depends on AGP && !X86_64 depends on AGP && X86
default GART_IOMMU
help
Say Y here to support the AMD 8151 AGP bridge and the builtin
GART on the AMD Athlon64/Opteron ("Hammer") CPUs.
config AGP_INTEL
tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
depends on AGP && X86 && !X86_64
help help
This option gives you AGP support for the GLX component of the This option gives you AGP support for the GLX component of the
XFree86 4.x on AMD Irongate, 761, and 762 chipsets. XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860
E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G,
852GM, 855GM and 865G integrated graphics chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N. use GLX or DRI, or if you have any Intel integrated graphics
chipsets. If unsure, say Y.
config AGP_NVIDIA
tristate "NVIDIA nForce/nForce2 chipset support"
depends on AGP && X86 && !X86_64
help
This option gives you AGP support for the GLX component of the
XFree86 4.x on the following NVIDIA chipsets. The supported chipsets
include nForce and nForce2
config AGP_SIS config AGP_SIS
tristate "Generic SiS support" tristate "SiS chipset support"
depends on AGP && !X86_64 depends on AGP && X86 && !X86_64
help help
This option gives you AGP support for the GLX component of the "soon This option gives you AGP support for the GLX component of the "soon
to be released" XFree86 4.x on Silicon Integrated Systems [SiS] to be released" XFree86 4.x on Silicon Integrated Systems [SiS]
...@@ -83,55 +95,39 @@ config AGP_SIS ...@@ -83,55 +95,39 @@ config AGP_SIS
You should say Y here if you use XFree86 3.3.6 or 4.x and want to You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N. use GLX or DRI. If unsure, say N.
config AGP_ALI
tristate "ALI chipset support"
depends on AGP && !X86_64
---help---
This option gives you AGP support for the GLX component of the
XFree86 4.x on the following ALi chipsets. The supported chipsets
include M1541, M1621, M1631, M1632, M1641,M1647,and M1651.
For the ALi-chipset question, ALi suggests you refer to
<http://www.ali.com.tw/eng/support/index.shtml>.
The M1541 chipset can do AGP 1x and 2x, but note that there is an
acknowledged incompatibility with Matrox G200 cards. Due to
timing issues, this chipset cannot do AGP 2x with the G200.
This is a hardware limitation. AGP 1x seems to be fine, though.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
config AGP_SWORKS config AGP_SWORKS
tristate "Serverworks LE/HE support" tristate "Serverworks LE/HE chipset support"
depends on AGP && !X86_64 depends on AGP && X86 && !X86_64
help help
Say Y here to support the Serverworks AGP card. See Say Y here to support the Serverworks AGP card. See
<http://www.serverworks.com/> for product descriptions and images. <http://www.serverworks.com/> for product descriptions and images.
config AGP_AMD_8151 config AGP_VIA
tristate "AMD 8151 support" tristate "VIA chipset support"
depends on AGP depends on AGP && X86 && !X86_64
default GART_IOMMU
help help
Say Y here to support the AMD 8151 AGP bridge and the builtin This option gives you AGP support for the GLX component of the
GART on the AMD Athlon64/Opteron ("Hammer") CPUs. XFree86 4.x on VIA MPV3/Apollo Pro chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
config AGP_I460 config AGP_I460
tristate "Intel 460GX support" tristate "Intel 460GX chipset support"
depends on AGP && IA64 depends on AGP && IA64
help help
This option gives you AGP GART support for the Intel 460GX chipset This option gives you AGP GART support for the Intel 460GX chipset
for IA64 processors. for IA64 processors.
config AGP_HP_ZX1 config AGP_HP_ZX1
tristate "HP ZX1 AGP support" tristate "HP ZX1 chipset AGP support"
depends on AGP && IA64 depends on AGP && IA64
help help
This option gives you AGP GART support for the HP ZX1 chipset This option gives you AGP GART support for the HP ZX1 chipset
for IA64 processors. for IA64 processors.
config AGP_ALPHA_CORE config AGP_ALPHA_CORE
tristate tristate "Alpha AGP support"
depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL) depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL)
default AGP default AGP
#
# Makefile for the agpgart device driver. This driver adds a user
# space ioctl interface to use agp memory. It also adds a kernel interface
# that other drivers could use to manipulate agp memory.
agpgart-y := backend.o frontend.o generic.o generic-3.0.o agpgart-y := backend.o frontend.o generic.o generic-3.0.o
agpgart-objs := $(agpgart-y)
obj-$(CONFIG_AGP) += agpgart.o
obj-$(CONFIG_AGP_INTEL) += intel-agp.o obj-$(CONFIG_AGP) += agpgart.o
obj-$(CONFIG_AGP_VIA) += via-agp.o
obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o
obj-$(CONFIG_AGP_SIS) += sis-agp.o
obj-$(CONFIG_AGP_ALI) += ali-agp.o obj-$(CONFIG_AGP_ALI) += ali-agp.o
obj-$(CONFIG_AGP_SWORKS) += sworks-agp.o obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o
obj-$(CONFIG_AGP_I460) += i460-agp.o
obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
obj-$(CONFIG_AGP_AMD_8151) += amd-k8-agp.o obj-$(CONFIG_AGP_AMD_8151) += amd-k8-agp.o
obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o
obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
obj-$(CONFIG_AGP_I460) += i460-agp.o
obj-$(CONFIG_AGP_INTEL) += intel-agp.o
obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o
obj-$(CONFIG_AGP_SIS) += sis-agp.o
obj-$(CONFIG_AGP_SWORKS) += sworks-agp.o
obj-$(CONFIG_AGP_VIA) += via-agp.o
...@@ -30,27 +30,16 @@ ...@@ -30,27 +30,16 @@
#include <asm/agp.h> /* for flush_agp_cache() */ #include <asm/agp.h> /* for flush_agp_cache() */
extern struct agp_bridge_data *agp_bridge;
#define PFX "agpgart: " #define PFX "agpgart: "
#ifdef CONFIG_SMP //#define AGP_DEBUG 1
static void ipi_handler(void *null) #ifdef AGP_DEBUG
{ #define DBG(x,y...) printk (KERN_DEBUG PFX "%s: " x "\n", __FUNCTION__ , ## y)
flush_agp_cache();
}
static void __attribute__((unused)) global_cache_flush(void)
{
if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0)
panic(PFX "timed out waiting for the other CPUs!\n");
}
#else #else
static void global_cache_flush(void) #define DBG(x,y...) do { } while (0)
{ #endif
flush_agp_cache();
} extern struct agp_bridge_data *agp_bridge;
#endif /* !CONFIG_SMP */
enum aper_size_type { enum aper_size_type {
U8_APER_SIZE, U8_APER_SIZE,
...@@ -101,14 +90,41 @@ struct aper_size_info_fixed { ...@@ -101,14 +90,41 @@ struct aper_size_info_fixed {
int page_order; int page_order;
}; };
struct agp_bridge_driver {
struct module *owner;
void *aperture_sizes;
int num_aperture_sizes;
enum aper_size_type size_type;
int cant_use_aperture;
int needs_scratch_page;
struct gatt_mask *masks;
int (*fetch_size)(void);
int (*configure)(void);
void (*agp_enable)(u32);
void (*cleanup)(void);
void (*tlb_flush)(agp_memory *);
unsigned long (*mask_memory)(unsigned long, int);
void (*cache_flush)(void);
int (*create_gatt_table)(void);
int (*free_gatt_table)(void);
int (*insert_memory)(agp_memory *, off_t, int);
int (*remove_memory)(agp_memory *, off_t, int);
agp_memory *(*alloc_by_type) (size_t, int);
void (*free_by_type)(agp_memory *);
void *(*agp_alloc_page)(void);
void (*agp_destroy_page)(void *);
int (*suspend)(void);
void (*resume)(void);
};
struct agp_bridge_data { struct agp_bridge_data {
struct agp_version *version; struct agp_version *version;
void *aperture_sizes; struct agp_bridge_driver *driver;
struct vm_operations_struct *vm_ops;
void *previous_size; void *previous_size;
void *current_size; void *current_size;
void *dev_private_data; void *dev_private_data;
struct pci_dev *dev; struct pci_dev *dev;
struct gatt_mask *masks;
u32 *gatt_table; u32 *gatt_table;
u32 *gatt_table_real; u32 *gatt_table_real;
unsigned long scratch_page; unsigned long scratch_page;
...@@ -117,38 +133,12 @@ struct agp_bridge_data { ...@@ -117,38 +133,12 @@ struct agp_bridge_data {
unsigned long gatt_bus_addr; unsigned long gatt_bus_addr;
u32 mode; u32 mode;
enum chipset_type type; enum chipset_type type;
enum aper_size_type size_type;
unsigned long *key_list; unsigned long *key_list;
atomic_t current_memory_agp; atomic_t current_memory_agp;
atomic_t agp_in_use; atomic_t agp_in_use;
int max_memory_agp; /* in number of pages */ int max_memory_agp; /* in number of pages */
int needs_scratch_page;
int aperture_size_idx; int aperture_size_idx;
int num_aperture_sizes;
int capndx; int capndx;
int cant_use_aperture;
struct vm_operations_struct *vm_ops;
/* Links to driver specific functions */
int (*fetch_size) (void);
int (*configure) (void);
void (*agp_enable) (u32);
void (*cleanup) (void);
void (*tlb_flush) (agp_memory *);
unsigned long (*mask_memory) (unsigned long, int);
void (*cache_flush) (void);
int (*create_gatt_table) (void);
int (*free_gatt_table) (void);
int (*insert_memory) (agp_memory *, off_t, int);
int (*remove_memory) (agp_memory *, off_t, int);
agp_memory *(*alloc_by_type) (size_t, int);
void (*free_by_type) (agp_memory *);
void *(*agp_alloc_page) (void);
void (*agp_destroy_page) (void *);
int (*suspend)(void);
void (*resume)(void);
}; };
#define OUTREG64(mmap, addr, val) __raw_writeq((val), (mmap)+(addr)) #define OUTREG64(mmap, addr, val) __raw_writeq((val), (mmap)+(addr))
...@@ -165,20 +155,17 @@ struct agp_bridge_data { ...@@ -165,20 +155,17 @@ struct agp_bridge_data {
#define MB(x) (KB (KB (x))) #define MB(x) (KB (KB (x)))
#define GB(x) (MB (KB (x))) #define GB(x) (MB (KB (x)))
#define CACHE_FLUSH agp_bridge->cache_flush
#define A_SIZE_8(x) ((struct aper_size_info_8 *) x) #define A_SIZE_8(x) ((struct aper_size_info_8 *) x)
#define A_SIZE_16(x) ((struct aper_size_info_16 *) x) #define A_SIZE_16(x) ((struct aper_size_info_16 *) x)
#define A_SIZE_32(x) ((struct aper_size_info_32 *) x) #define A_SIZE_32(x) ((struct aper_size_info_32 *) x)
#define A_SIZE_LVL2(x) ((struct aper_size_info_lvl2 *) x) #define A_SIZE_LVL2(x) ((struct aper_size_info_lvl2 *) x)
#define A_SIZE_FIX(x) ((struct aper_size_info_fixed *) x) #define A_SIZE_FIX(x) ((struct aper_size_info_fixed *) x)
#define A_IDX8() (A_SIZE_8(agp_bridge->aperture_sizes) + i) #define A_IDX8(bridge) (A_SIZE_8((bridge)->driver->aperture_sizes) + i)
#define A_IDX16() (A_SIZE_16(agp_bridge->aperture_sizes) + i) #define A_IDX16(bridge) (A_SIZE_16((bridge)->driver->aperture_sizes) + i)
#define A_IDX32() (A_SIZE_32(agp_bridge->aperture_sizes) + i) #define A_IDX32(bridge) (A_SIZE_32((bridge)->driver->aperture_sizes) + i)
#define A_IDXLVL2() (A_SIZE_LVL2(agp_bridge->aperture_sizes) + i)
#define A_IDXFIX() (A_SIZE_FIX(agp_bridge->aperture_sizes) + i)
#define MAXKEY (4096 * 32) #define MAXKEY (4096 * 32)
#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge->scratch_page) #define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page)
/* intel register */ /* intel register */
#define INTEL_APBASE 0x10 #define INTEL_APBASE 0x10
...@@ -374,11 +361,15 @@ struct agp_device_ids { ...@@ -374,11 +361,15 @@ struct agp_device_ids {
int (*chipset_setup) (struct pci_dev *pdev); /* used to override generic */ int (*chipset_setup) (struct pci_dev *pdev); /* used to override generic */
}; };
struct agp_driver { /* Driver registration */
struct module *owner; struct agp_bridge_data *agp_alloc_bridge(void);
struct pci_dev *dev; void agp_put_bridge(struct agp_bridge_data *bridge);
}; int agp_add_bridge(struct agp_bridge_data *bridge);
void agp_remove_bridge(struct agp_bridge_data *bridge);
/* Frontend routines. */
int agp_frontend_initialize(void);
void agp_frontend_cleanup(void);
/* Generic routines. */ /* Generic routines. */
void agp_generic_enable(u32 mode); void agp_generic_enable(u32 mode);
...@@ -395,10 +386,29 @@ int agp_generic_suspend(void); ...@@ -395,10 +386,29 @@ int agp_generic_suspend(void);
void agp_generic_resume(void); void agp_generic_resume(void);
void agp_free_key(int key); void agp_free_key(int key);
int agp_num_entries(void); int agp_num_entries(void);
int agp_register_driver (struct agp_driver *drv);
int agp_unregister_driver(struct agp_driver *drv);
u32 agp_collect_device_status(u32 mode, u32 command); u32 agp_collect_device_status(u32 mode, u32 command);
void agp_device_command(u32 command, int agp_v3); void agp_device_command(u32 command, int agp_v3);
int agp_3_0_node_enable(u32 mode, u32 minor); int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor);
void global_cache_flush(void);
/* Standard agp registers */
#define AGPSTAT 0x4
#define AGPCMD 0x8
#define AGPNEPG 0x16
#define AGP_MAJOR_VERSION_SHIFT (20)
#define AGP_MINOR_VERSION_SHIFT (16)
#define AGPSTAT_RQ_DEPTH (0xff000000)
#define AGPSTAT_ARQSZ_SHIFT 13
#define AGPSTAT_AGP_ENABLE (1<<8)
#define AGPSTAT_SBA (1<<9)
#define AGPSTAT2_1X (1<<0)
#define AGPSTAT2_2X (1<<1)
#define AGPSTAT2_4X (1<<2)
#define AGPSTAT_FW (1<<4)
#endif /* _AGP_BACKEND_PRIV_H */ #endif /* _AGP_BACKEND_PRIV_H */
...@@ -19,9 +19,9 @@ static int ali_fetch_size(void) ...@@ -19,9 +19,9 @@ static int ali_fetch_size(void)
pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
temp &= ~(0xfffffff0); temp &= ~(0xfffffff0);
values = A_SIZE_32(agp_bridge->aperture_sizes); values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -118,47 +118,51 @@ static unsigned long ali_mask_memory(unsigned long addr, int type) ...@@ -118,47 +118,51 @@ static unsigned long ali_mask_memory(unsigned long addr, int type)
{ {
/* Memory type is ignored */ /* Memory type is ignored */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static void ali_cache_flush(void) static void m1541_cache_flush(void)
{ {
int i, page_count;
u32 temp;
global_cache_flush(); global_cache_flush();
if (agp_bridge->type == ALI_M1541) { page_count = 1 << A_SIZE_32(agp_bridge->current_size)->page_order;
int i, page_count; for (i = 0; i < PAGE_SIZE * page_count; i += PAGE_SIZE) {
u32 temp; pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
&temp);
page_count = 1 << A_SIZE_32(agp_bridge->current_size)->page_order; pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
for (i = 0; i < PAGE_SIZE * page_count; i += PAGE_SIZE) { (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); (agp_bridge->gatt_bus_addr + i)) |
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, ALI_CACHE_FLUSH_EN));
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
(agp_bridge->gatt_bus_addr + i)) |
ALI_CACHE_FLUSH_EN));
}
} }
} }
static void *ali_alloc_page(void) static void *m1541_alloc_page(void)
{ {
void *adr = agp_generic_alloc_page(); void *addr = agp_generic_alloc_page();
u32 temp; u32 temp;
if (adr == 0) if (!addr)
return 0; return NULL;
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN ));
return addr;
}
if (agp_bridge->type == ALI_M1541) { static void ali_destroy_page(void * addr)
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); {
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, if (addr) {
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) | global_cache_flush(); /* is this really needed? --hch */
virt_to_phys(adr)) | agp_generic_destroy_page(addr);
ALI_CACHE_FLUSH_EN ));
} }
return adr;
} }
static void ali_destroy_page(void * addr) static void m1541_destroy_page(void * addr)
{ {
u32 temp; u32 temp;
...@@ -167,17 +171,14 @@ static void ali_destroy_page(void * addr) ...@@ -167,17 +171,14 @@ static void ali_destroy_page(void * addr)
global_cache_flush(); global_cache_flush();
if (agp_bridge->type == ALI_M1541) { pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) | virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN));
virt_to_phys(addr)) |
ALI_CACHE_FLUSH_EN));
}
agp_generic_destroy_page(addr); agp_generic_destroy_page(addr);
} }
/* Setup function */ /* Setup function */
static struct gatt_mask ali_generic_masks[] = static struct gatt_mask ali_generic_masks[] =
{ {
...@@ -195,170 +196,185 @@ static struct aper_size_info_32 ali_generic_sizes[7] = ...@@ -195,170 +196,185 @@ static struct aper_size_info_32 ali_generic_sizes[7] =
{4, 1024, 0, 3} {4, 1024, 0, 3}
}; };
static int __init ali_generic_setup (struct pci_dev *pdev) struct agp_bridge_driver ali_generic_bridge = {
{ .owner = THIS_MODULE,
agp_bridge->masks = ali_generic_masks; .masks = ali_generic_masks,
agp_bridge->aperture_sizes = (void *) ali_generic_sizes; .aperture_sizes = ali_generic_sizes,
agp_bridge->size_type = U32_APER_SIZE; .size_type = U32_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 7,
agp_bridge->dev_private_data = NULL; .configure = ali_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = ali_fetch_size,
agp_bridge->configure = ali_configure; .cleanup = ali_cleanup,
agp_bridge->fetch_size = ali_fetch_size; .tlb_flush = ali_tlbflush,
agp_bridge->cleanup = ali_cleanup; .mask_memory = ali_mask_memory,
agp_bridge->tlb_flush = ali_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = ali_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = ali_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = ali_destroy_page,
agp_bridge->agp_alloc_page = ali_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = ali_destroy_page; .resume = agp_generic_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0; struct agp_bridge_driver ali_m1541_bridge = {
return 0; .owner = THIS_MODULE,
} .masks = ali_generic_masks,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = ali_configure,
.fetch_size = ali_fetch_size,
.cleanup = ali_cleanup,
.tlb_flush = ali_tlbflush,
.mask_memory = ali_mask_memory,
.agp_enable = agp_generic_enable,
.cache_flush = m1541_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = m1541_alloc_page,
.agp_destroy_page = m1541_destroy_page,
.suspend = agp_generic_suspend,
.resume = agp_generic_resume,
};
struct agp_device_ids ali_agp_device_ids[] __initdata = struct agp_device_ids ali_agp_device_ids[] __initdata =
{ {
{ {
.device_id = PCI_DEVICE_ID_AL_M1541, .device_id = PCI_DEVICE_ID_AL_M1541,
.chipset = ALI_M1541,
.chipset_name = "M1541", .chipset_name = "M1541",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1621, .device_id = PCI_DEVICE_ID_AL_M1621,
.chipset = ALI_M1621,
.chipset_name = "M1621", .chipset_name = "M1621",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1631, .device_id = PCI_DEVICE_ID_AL_M1631,
.chipset = ALI_M1631,
.chipset_name = "M1631", .chipset_name = "M1631",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1632, .device_id = PCI_DEVICE_ID_AL_M1632,
.chipset = ALI_M1632,
.chipset_name = "M1632", .chipset_name = "M1632",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1641, .device_id = PCI_DEVICE_ID_AL_M1641,
.chipset = ALI_M1641,
.chipset_name = "M1641", .chipset_name = "M1641",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1644, .device_id = PCI_DEVICE_ID_AL_M1644,
.chipset = ALI_M1644,
.chipset_name = "M1644", .chipset_name = "M1644",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1647, .device_id = PCI_DEVICE_ID_AL_M1647,
.chipset = ALI_M1647,
.chipset_name = "M1647", .chipset_name = "M1647",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1651, .device_id = PCI_DEVICE_ID_AL_M1651,
.chipset = ALI_M1651,
.chipset_name = "M1651", .chipset_name = "M1651",
}, },
{ {
.device_id = PCI_DEVICE_ID_AL_M1671, .device_id = PCI_DEVICE_ID_AL_M1671,
.chipset = ALI_M1671,
.chipset_name = "M1671", .chipset_name = "M1671",
}, },
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
/* scan table above for supported devices */ static int __init agp_ali_probe(struct pci_dev *pdev,
static int __init agp_lookup_host_bridge (struct pci_dev *pdev) const struct pci_device_id *ent)
{ {
int j=0; struct agp_device_ids *devs = ali_agp_device_ids;
struct agp_device_ids *devs; struct agp_bridge_data *bridge;
u8 hidden_1621_id, cap_ptr;
devs = ali_agp_device_ids; int j;
while (devs[j].chipset_name != NULL) { cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (pdev->device == devs[j].device_id) { if (!cap_ptr)
if (pdev->device == PCI_DEVICE_ID_AL_M1621) { return -ENODEV;
u8 hidden_1621_id;
/* probe for known chipsets */
pci_read_config_byte(pdev, 0xFB, &hidden_1621_id); for (j = 0; devs[j].chipset_name; j++) {
switch (hidden_1621_id) { if (pdev->device == devs[j].device_id)
case 0x31: goto found;
devs[j].chipset_name="M1631";
break;
case 0x32:
devs[j].chipset_name="M1632";
break;
case 0x41:
devs[j].chipset_name="M1641";
break;
case 0x43:
break;
case 0x47:
devs[j].chipset_name="M1647";
break;
case 0x51:
devs[j].chipset_name="M1651";
break;
default:
break;
}
}
printk (KERN_INFO PFX "Detected ALi %s chipset\n",
devs[j].chipset_name);
agp_bridge->type = devs[j].chipset;
if (devs[j].chipset_setup != NULL)
return devs[j].chipset_setup(pdev);
else
return ali_generic_setup(pdev);
}
j++;
} }
/* try init anyway, if user requests it */ if (!agp_try_unsupported) {
if (agp_try_unsupported) { printk(KERN_ERR PFX
printk(KERN_WARNING PFX "Trying generic ALi routines" "Unsupported ALi chipset (device id: %04x),"
" for device id: %04x\n", pdev->device); " you might want to try agp_try_unsupported=1.\n",
agp_bridge->type = ALI_GENERIC; pdev->device);
return ali_generic_setup(pdev); return -ENODEV;
} }
printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x)," printk(KERN_WARNING PFX "Trying generic ALi routines"
" you might want to try agp_try_unsupported=1.\n", pdev->device); " for device id: %04x\n", pdev->device);
return -ENODEV;
} found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
switch (pdev->device) {
case PCI_DEVICE_ID_AL_M1541:
bridge->driver = &ali_m1541_bridge;
break;
case PCI_DEVICE_ID_AL_M1621:
pci_read_config_byte(pdev, 0xFB, &hidden_1621_id);
switch (hidden_1621_id) {
case 0x31:
devs[j].chipset_name = "M1631";
break;
case 0x32:
devs[j].chipset_name = "M1632";
break;
case 0x41:
devs[j].chipset_name = "M1641";
break;
case 0x43:
break;
case 0x47:
devs[j].chipset_name = "M1647";
break;
case 0x51:
devs[j].chipset_name = "M1651";
break;
default:
break;
}
/*FALLTHROUGH*/
default:
bridge->driver = &ali_generic_bridge;
}
static struct agp_driver ali_agp_driver = { printk(KERN_INFO PFX "Detected ALi %s chipset\n",
.owner = THIS_MODULE, devs[j].chipset_name);
};
static int __init agp_ali_probe (struct pci_dev *dev, const struct pci_device_id *ent) /* Fill in the mode register */
{ pci_read_config_dword(pdev,
u8 cap_ptr = 0; bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); pci_set_drvdata(pdev, bridge);
if (cap_ptr == 0) return agp_add_bridge(bridge);
return -ENODEV; }
/* probe for known chipsets */ static void __devexit agp_ali_remove(struct pci_dev *pdev)
if (agp_lookup_host_bridge(dev) != -ENODEV) { {
agp_bridge->dev = dev; struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_bridge->capndx = cap_ptr;
/* Fill in the mode register */ agp_remove_bridge(bridge);
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); agp_put_bridge(bridge);
ali_agp_driver.dev = dev;
agp_register_driver(&ali_agp_driver);
return 0;
}
return -ENODEV;
} }
static struct pci_device_id agp_ali_pci_table[] __initdata = { static struct pci_device_id agp_ali_pci_table[] __initdata = {
...@@ -379,22 +395,16 @@ static struct __initdata pci_driver agp_ali_pci_driver = { ...@@ -379,22 +395,16 @@ static struct __initdata pci_driver agp_ali_pci_driver = {
.name = "agpgart-ali", .name = "agpgart-ali",
.id_table = agp_ali_pci_table, .id_table = agp_ali_pci_table,
.probe = agp_ali_probe, .probe = agp_ali_probe,
.remove = agp_ali_remove,
}; };
static int __init agp_ali_init(void) static int __init agp_ali_init(void)
{ {
int ret_val; return pci_module_init(&agp_ali_pci_driver);
ret_val = pci_module_init(&agp_ali_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_ali_cleanup(void) static void __exit agp_ali_cleanup(void)
{ {
agp_unregister_driver(&ali_agp_driver);
pci_unregister_driver(&agp_ali_pci_driver); pci_unregister_driver(&agp_ali_pci_driver);
} }
......
...@@ -81,7 +81,7 @@ static void alpha_core_agp_tlbflush(agp_memory *mem) ...@@ -81,7 +81,7 @@ static void alpha_core_agp_tlbflush(agp_memory *mem)
static unsigned long alpha_core_agp_mask_memory(unsigned long addr, int type) static unsigned long alpha_core_agp_mask_memory(unsigned long addr, int type)
{ {
/* Memory type is ignored */ /* Memory type is ignored */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static void alpha_core_agp_enable(u32 mode) static void alpha_core_agp_enable(u32 mode)
...@@ -109,7 +109,7 @@ static int alpha_core_agp_insert_memory(agp_memory *mem, off_t pg_start, ...@@ -109,7 +109,7 @@ static int alpha_core_agp_insert_memory(agp_memory *mem, off_t pg_start,
status = agp->ops->bind(agp, pg_start, mem); status = agp->ops->bind(agp, pg_start, mem);
mb(); mb();
agp_bridge->tlb_flush(mem); alpha_core_agp_tlbflush(mem);
return status; return status;
} }
...@@ -121,29 +121,57 @@ static int alpha_core_agp_remove_memory(agp_memory *mem, off_t pg_start, ...@@ -121,29 +121,57 @@ static int alpha_core_agp_remove_memory(agp_memory *mem, off_t pg_start,
int status; int status;
status = agp->ops->unbind(agp, pg_start, mem); status = agp->ops->unbind(agp, pg_start, mem);
agp_bridge->tlb_flush(mem); alpha_core_agp_tlbflush(mem);
return status; return status;
} }
struct agp_bridge_driver alpha_core_agp_driver = {
static struct agp_driver alpha_core_agp_driver = { .owner = THIS_MODULE,
.owner = THIS_MODULE, .masks = alpha_core_agp_masks,
.aperture_sizes = aper_size,
.current_size = aper_size, /* only one entry */
.size_type = FIXED_APER_SIZE,
.num_aperture_sizes = 1,
.configure = alpha_core_agp_configure,
.fetch_size = alpha_core_agp_fetch_size,
.cleanup = alpha_core_agp_cleanup,
.tlb_flush = alpha_core_agp_tlbflush,
.mask_memory = alpha_core_agp_mask_memory,
.agp_enable = alpha_core_agp_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = alpha_core_agp_nop,
.free_gatt_table = alpha_core_agp_nop,
.insert_memory = alpha_core_agp_insert_memory,
.remove_memory = alpha_core_agp_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.mode = agp->capability.lw,
.cant_use_aperture = 1,
.vm_ops = &alpha_core_agp_vm_ops,
}; };
struct agp_bridge_data *alpha_bridge;
int __init int __init
alpha_core_agp_setup(void) alpha_core_agp_setup(void)
{ {
alpha_agp_info *agp = alpha_mv.agp_info(); alpha_agp_info *agp = alpha_mv.agp_info();
struct pci_dev *pdev; /* faked */
struct aper_size_info_fixed *aper_size; struct aper_size_info_fixed *aper_size;
if (!agp) return -ENODEV; if (!agp)
if (agp->ops->setup(agp)) return -ENODEV; return -ENODEV;
if (agp->ops->setup(agp))
return -ENODEV;
/* /*
* Build the aperture size descriptor * Build the aperture size descriptor
*/ */
aper_size = alpha_core_agp_sizes; aper_size = alpha_core_agp_sizes;
if (!aper_size) return -ENOMEM; if (!aper_size)
return -ENOMEM;
aper_size->size = agp->aperture.size / (1024 * 1024); aper_size->size = agp->aperture.size / (1024 * 1024);
aper_size->num_entries = agp->aperture.size / PAGE_SIZE; aper_size->num_entries = agp->aperture.size / PAGE_SIZE;
aper_size->page_order = ffs(aper_size->num_entries / 1024) - 1; aper_size->page_order = ffs(aper_size->num_entries / 1024) - 1;
...@@ -151,63 +179,40 @@ alpha_core_agp_setup(void) ...@@ -151,63 +179,40 @@ alpha_core_agp_setup(void)
/* /*
* Build a fake pci_dev struct * Build a fake pci_dev struct
*/ */
if (!(agp_bridge->dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL))) { pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
if (!pdev)
return -ENOMEM; return -ENOMEM;
} pdev->vendor = 0xffff;
agp_bridge->dev->vendor = 0xffff; pdev->device = 0xffff;
agp_bridge->dev->device = 0xffff; pdev->sysdata = agp->hose;
agp_bridge->dev->sysdata = agp->hose;
alpha_bridge = agp_alloc_bridge();
if (!alpha_bridge)
goto fail;
alpha_bridge->driver = &alpha_core_agp_driver;
alpha_bridge->dev_private_data = agp;
alpha_bridge->dev = pdev;
/*
* Fill in the rest of the agp_bridge struct
*/
agp_bridge->masks = alpha_core_agp_masks;
agp_bridge->aperture_sizes = aper_size;
agp_bridge->current_size = aper_size; /* only one entry */
agp_bridge->size_type = FIXED_APER_SIZE;
agp_bridge->num_aperture_sizes = 1;
agp_bridge->dev_private_data = agp;
agp_bridge->needs_scratch_page = FALSE;
agp_bridge->configure = alpha_core_agp_configure;
agp_bridge->fetch_size = alpha_core_agp_fetch_size;
agp_bridge->cleanup = alpha_core_agp_cleanup;
agp_bridge->tlb_flush = alpha_core_agp_tlbflush;
agp_bridge->mask_memory = alpha_core_agp_mask_memory;
agp_bridge->agp_enable = alpha_core_agp_enable;
agp_bridge->cache_flush = global_cache_flush;
agp_bridge->create_gatt_table = alpha_core_agp_nop;
agp_bridge->free_gatt_table = alpha_core_agp_nop;
agp_bridge->insert_memory = alpha_core_agp_insert_memory;
agp_bridge->remove_memory = alpha_core_agp_remove_memory;
agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
agp_bridge->free_by_type = agp_generic_free_by_type;
agp_bridge->agp_alloc_page = agp_generic_alloc_page;
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->mode = agp->capability.lw;
agp_bridge->cant_use_aperture = 1;
agp_bridge->vm_ops = &alpha_core_agp_vm_ops;
alpha_core_agp_driver.dev = agp_bridge->dev;
agp_register_driver(&alpha_core_agp_driver);
printk(KERN_INFO "Detected AGP on hose %d\n", agp->hose->index); printk(KERN_INFO "Detected AGP on hose %d\n", agp->hose->index);
return 0; return agp_add_bridge(alpha_bridge);
fail:
kfree(pdev);
return -ENOMEM;
} }
static int __init agp_alpha_core_init(void) static int __init agp_alpha_core_init(void)
{ {
int ret_val = -ENODEV; if (alpha_mv.agp_info)
if (alpha_mv.agp_info) { return alpha_core_agp_setup();
agp_bridge->type = ALPHA_CORE_AGP; return -ENODEV;
ret_val = alpha_core_agp_setup();
}
return ret_val;
} }
static void __exit agp_alpha_core_cleanup(void) static void __exit agp_alpha_core_cleanup(void)
{ {
agp_unregister_driver(&alpha_core_agp_driver); agp_remove_bridge(alpha_bridge);
/* no pci driver for core */ agp_put_bridge(alpha_bridge);
} }
module_init(agp_alpha_core_init); module_init(agp_alpha_core_init);
......
...@@ -33,7 +33,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) ...@@ -33,7 +33,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
return -ENOMEM; return -ENOMEM;
} }
SetPageReserved(virt_to_page(page_map->real)); SetPageReserved(virt_to_page(page_map->real));
CACHE_FLUSH(); global_cache_flush();
page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
PAGE_SIZE); PAGE_SIZE);
if (page_map->remapped == NULL) { if (page_map->remapped == NULL) {
...@@ -42,7 +42,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) ...@@ -42,7 +42,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
page_map->real = NULL; page_map->real = NULL;
return -ENOMEM; return -ENOMEM;
} }
CACHE_FLUSH(); global_cache_flush();
for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
page_map->remapped[i] = agp_bridge->scratch_page; page_map->remapped[i] = agp_bridge->scratch_page;
...@@ -75,6 +75,7 @@ static void amd_free_gatt_pages(void) ...@@ -75,6 +75,7 @@ static void amd_free_gatt_pages(void)
} }
} }
kfree(tables); kfree(tables);
amd_irongate_private.gatt_pages = NULL;
} }
static int amd_create_gatt_pages(int nr_tables) static int amd_create_gatt_pages(int nr_tables)
...@@ -184,8 +185,8 @@ static int amd_irongate_fetch_size(void) ...@@ -184,8 +185,8 @@ static int amd_irongate_fetch_size(void)
pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp); pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
temp = (temp & 0x0000000e); temp = (temp & 0x0000000e);
values = A_SIZE_LVL2(agp_bridge->aperture_sizes); values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -274,7 +275,7 @@ static unsigned long amd_irongate_mask_memory(unsigned long addr, int type) ...@@ -274,7 +275,7 @@ static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
{ {
/* Only type 0 is supported by the irongate */ /* Only type 0 is supported by the irongate */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static int amd_insert_memory(agp_memory * mem, static int amd_insert_memory(agp_memory * mem,
...@@ -297,14 +298,13 @@ static int amd_insert_memory(agp_memory * mem, ...@@ -297,14 +298,13 @@ static int amd_insert_memory(agp_memory * mem,
while (j < (pg_start + mem->page_count)) { while (j < (pg_start + mem->page_count)) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr); cur_gatt = GET_GATT(addr);
if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) { if (!PGE_EMPTY(agp_bridge, cur_gatt[GET_GATT_OFF(addr)]))
return -EBUSY; return -EBUSY;
}
j++; j++;
} }
if (mem->is_flushed == FALSE) { if (mem->is_flushed == FALSE) {
CACHE_FLUSH(); global_cache_flush();
mem->is_flushed = TRUE; mem->is_flushed = TRUE;
} }
...@@ -312,9 +312,9 @@ static int amd_insert_memory(agp_memory * mem, ...@@ -312,9 +312,9 @@ static int amd_insert_memory(agp_memory * mem,
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr); cur_gatt = GET_GATT(addr);
cur_gatt[GET_GATT_OFF(addr)] = cur_gatt[GET_GATT_OFF(addr)] =
agp_bridge->mask_memory(mem->memory[i], mem->type); amd_irongate_mask_memory(mem->memory[i], mem->type);
} }
agp_bridge->tlb_flush(mem); amd_irongate_tlbflush(mem);
return 0; return 0;
} }
...@@ -335,7 +335,7 @@ static int amd_remove_memory(agp_memory * mem, off_t pg_start, ...@@ -335,7 +335,7 @@ static int amd_remove_memory(agp_memory * mem, off_t pg_start,
(unsigned long) agp_bridge->scratch_page; (unsigned long) agp_bridge->scratch_page;
} }
agp_bridge->tlb_flush(mem); amd_irongate_tlbflush(mem);
return 0; return 0;
} }
...@@ -355,115 +355,104 @@ static struct gatt_mask amd_irongate_masks[] = ...@@ -355,115 +355,104 @@ static struct gatt_mask amd_irongate_masks[] =
{.mask = 0x00000001, .type = 0} {.mask = 0x00000001, .type = 0}
}; };
static int __init amd_irongate_setup (struct pci_dev *pdev) struct agp_bridge_driver amd_irongate_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = amd_irongate_masks; .masks = amd_irongate_masks,
agp_bridge->aperture_sizes = (void *) amd_irongate_sizes; .aperture_sizes = amd_irongate_sizes,
agp_bridge->size_type = LVL2_APER_SIZE; .size_type = LVL2_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 7,
agp_bridge->dev_private_data = (void *) &amd_irongate_private; .configure = amd_irongate_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = amd_irongate_fetch_size,
agp_bridge->configure = amd_irongate_configure; .cleanup = amd_irongate_cleanup,
agp_bridge->fetch_size = amd_irongate_fetch_size; .tlb_flush = amd_irongate_tlbflush,
agp_bridge->cleanup = amd_irongate_cleanup; .mask_memory = amd_irongate_mask_memory,
agp_bridge->tlb_flush = amd_irongate_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = amd_irongate_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = amd_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = amd_free_gatt_table,
agp_bridge->create_gatt_table = amd_create_gatt_table; .insert_memory = amd_insert_memory,
agp_bridge->free_gatt_table = amd_free_gatt_table; .remove_memory = amd_remove_memory,
agp_bridge->insert_memory = amd_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = amd_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = agp_generic_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
struct agp_device_ids amd_agp_device_ids[] __initdata = struct agp_device_ids amd_agp_device_ids[] __initdata =
{ {
{ {
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006, .device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006,
.chipset = AMD_IRONGATE,
.chipset_name = "Irongate", .chipset_name = "Irongate",
}, },
{ {
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_700E, .device_id = PCI_DEVICE_ID_AMD_FE_GATE_700E,
.chipset = AMD_761,
.chipset_name = "761", .chipset_name = "761",
}, },
{ {
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_700C, .device_id = PCI_DEVICE_ID_AMD_FE_GATE_700C,
.chipset = AMD_762,
.chipset_name = "760MP", .chipset_name = "760MP",
}, },
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
static int __init agp_amdk7_probe(struct pci_dev *pdev,
/* scan table above for supported devices */ const struct pci_device_id *ent)
static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
{ {
int j=0; struct agp_device_ids *devs = amd_agp_device_ids;
struct agp_device_ids *devs; struct agp_bridge_data *bridge;
u8 cap_ptr;
devs = amd_agp_device_ids; int j;
while (devs[j].chipset_name != NULL) { cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (pdev->device == devs[j].device_id) { if (!cap_ptr)
printk (KERN_INFO PFX "Detected AMD %s chipset\n", devs[j].chipset_name); return -ENODEV;
agp_bridge->type = devs[j].chipset;
if (devs[j].chipset_setup != NULL) for (j = 0; devs[j].chipset_name; j++) {
return devs[j].chipset_setup(pdev); if (pdev->device == devs[j].device_id) {
else printk (KERN_INFO PFX "Detected AMD %s chipset\n",
return amd_irongate_setup(pdev); devs[j].chipset_name);
goto found;
} }
j++;
} }
/* try init anyway, if user requests it */ if (!agp_try_unsupported) {
if (agp_try_unsupported) { printk(KERN_ERR PFX
printk(KERN_WARNING PFX "Trying generic AMD routines" "Unsupported AMD chipset (device id: %04x),"
" for device id: %04x\n", pdev->device); " you might want to try agp_try_unsupported=1.\n",
agp_bridge->type = AMD_GENERIC; pdev->device);
return amd_irongate_setup(pdev); return -ENODEV;
} }
printk(KERN_ERR PFX "Unsupported AMD chipset (device id: %04x)," printk(KERN_WARNING PFX "Trying generic AMD routines"
" you might want to try agp_try_unsupported=1.\n", pdev->device); " for device id: %04x\n", pdev->device);
return -ENODEV;
}
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
static struct agp_driver amd_k7_agp_driver = { bridge->driver = &amd_irongate_driver;
.owner = THIS_MODULE, bridge->dev_private_data = &amd_irongate_private,
}; bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Supported Device Scanning routine */ /* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
static int __init agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_id *ent) pci_set_drvdata(pdev, bridge);
{ return agp_add_bridge(bridge);
u8 cap_ptr = 0; }
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); static void __devexit agp_amdk7_remove(struct pci_dev *pdev)
if (cap_ptr == 0) {
return -ENODEV; struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
if (agp_lookup_host_bridge(dev) != -ENODEV) { agp_remove_bridge(bridge);
agp_bridge->dev = dev; agp_put_bridge(bridge);
agp_bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
amd_k7_agp_driver.dev = dev;
agp_register_driver(&amd_k7_agp_driver);
return 0;
}
return -ENODEV;
} }
static struct pci_device_id agp_amdk7_pci_table[] __initdata = { static struct pci_device_id agp_amdk7_pci_table[] __initdata = {
...@@ -484,22 +473,16 @@ static struct __initdata pci_driver agp_amdk7_pci_driver = { ...@@ -484,22 +473,16 @@ static struct __initdata pci_driver agp_amdk7_pci_driver = {
.name = "agpgart-amdk7", .name = "agpgart-amdk7",
.id_table = agp_amdk7_pci_table, .id_table = agp_amdk7_pci_table,
.probe = agp_amdk7_probe, .probe = agp_amdk7_probe,
.remove = agp_amdk7_remove,
}; };
static int __init agp_amdk7_init(void) static int __init agp_amdk7_init(void)
{ {
int ret_val; return pci_module_init(&agp_amdk7_pci_driver);
ret_val = pci_module_init(&agp_amdk7_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_amdk7_cleanup(void) static void __exit agp_amdk7_cleanup(void)
{ {
agp_unregister_driver(&amd_k7_agp_driver);
pci_unregister_driver(&agp_amdk7_pci_driver); pci_unregister_driver(&agp_amdk7_pci_driver);
} }
...@@ -508,4 +491,3 @@ module_exit(agp_amdk7_cleanup); ...@@ -508,4 +491,3 @@ module_exit(agp_amdk7_cleanup);
MODULE_PARM(agp_try_unsupported, "1i"); MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights"); MODULE_LICENSE("GPL and additional rights");
...@@ -29,6 +29,21 @@ static struct pci_dev * hammers[MAX_HAMMER_GARTS]; ...@@ -29,6 +29,21 @@ static struct pci_dev * hammers[MAX_HAMMER_GARTS];
static int gart_iterator; static int gart_iterator;
#define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++) #define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
static void flush_x86_64_tlb(struct pci_dev *dev)
{
u32 tmp;
pci_read_config_dword (dev, AMD_X86_64_GARTCACHECTL, &tmp);
tmp |= 1<<0;
pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
}
static void amd_x86_64_tlbflush(agp_memory *temp)
{
for_each_nb()
flush_x86_64_tlb(hammers[gart_iterator]);
}
static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type) static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
{ {
int i, j, num_entries; int i, j, num_entries;
...@@ -50,18 +65,18 @@ static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -50,18 +65,18 @@ static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
/* gatt table should be empty. */ /* gatt table should be empty. */
while (j < (pg_start + mem->page_count)) { while (j < (pg_start + mem->page_count)) {
if (!PGE_EMPTY(agp_bridge->gatt_table[j])) if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[j]))
return -EBUSY; return -EBUSY;
j++; j++;
} }
if (mem->is_flushed == FALSE) { if (mem->is_flushed == FALSE) {
CACHE_FLUSH(); global_cache_flush();
mem->is_flushed = TRUE; mem->is_flushed = TRUE;
} }
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
addr = agp_bridge->mask_memory(mem->memory[i], mem->type); addr = agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
tmp = addr; tmp = addr;
BUG_ON(tmp & 0xffffff0000000ffc); BUG_ON(tmp & 0xffffff0000000ffc);
...@@ -71,7 +86,7 @@ static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -71,7 +86,7 @@ static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
agp_bridge->gatt_table[j] = pte; agp_bridge->gatt_table[j] = pte;
} }
agp_bridge->tlb_flush(mem); amd_x86_64_tlbflush(mem);
return 0; return 0;
} }
...@@ -113,7 +128,7 @@ static int amd_x86_64_fetch_size(void) ...@@ -113,7 +128,7 @@ static int amd_x86_64_fetch_size(void)
temp = (temp & 0xe); temp = (temp & 0xe);
values = A_SIZE_32(x86_64_aperture_sizes); values = A_SIZE_32(x86_64_aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -125,25 +140,6 @@ static int amd_x86_64_fetch_size(void) ...@@ -125,25 +140,6 @@ static int amd_x86_64_fetch_size(void)
return 0; return 0;
} }
static void flush_x86_64_tlb(struct pci_dev *dev)
{
u32 tmp;
pci_read_config_dword (dev, AMD_X86_64_GARTCACHECTL, &tmp);
tmp |= 1<<0;
pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
}
static void amd_x86_64_tlbflush(agp_memory * temp)
{
for_each_nb() {
flush_x86_64_tlb (hammers[gart_iterator]);
}
}
/* /*
* In a multiprocessor x86-64 system, this function gets * In a multiprocessor x86-64 system, this function gets
* called once for each CPU. * called once for each CPU.
...@@ -218,7 +214,7 @@ static void amd_8151_cleanup(void) ...@@ -218,7 +214,7 @@ static void amd_8151_cleanup(void)
static unsigned long amd_8151_mask_memory(unsigned long addr, int type) static unsigned long amd_8151_mask_memory(unsigned long addr, int type)
{ {
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
...@@ -227,130 +223,84 @@ static struct gatt_mask amd_8151_masks[] = ...@@ -227,130 +223,84 @@ static struct gatt_mask amd_8151_masks[] =
{.mask = 0x00000001, .type = 0} {.mask = 0x00000001, .type = 0}
}; };
struct agp_bridge_driver amd_8151_driver = {
.owner = THIS_MODULE,
.masks = amd_8151_masks,
.aperture_sizes = amd_8151_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = amd_8151_configure,
.fetch_size = amd_x86_64_fetch_size,
.cleanup = amd_8151_cleanup,
.tlb_flush = amd_x86_64_tlbflush,
.mask_memory = amd_8151_mask_memory,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = x86_64_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.suspend = agp_generic_suspend,
.resume = agp_generic_resume,
};
/* static int __init agp_amdk8_probe(struct pci_dev *pdev,
* Try to configure an AGP v3 capable setup. const struct pci_device_id *ent)
* If we fail (typically because we don't have an AGP v3
* card in the system) we fall back to the generic AGP v2
* routines.
*/
static void agp_x86_64_agp_enable(u32 mode)
{ {
struct pci_dev *device = NULL; struct agp_bridge_data *bridge;
u32 command, scratch; struct pci_dev *loop_dev;
u8 cap_ptr; u8 cap_ptr;
u8 v3_devs=0; int i = 0;
/* FIXME: If 'mode' is x1/x2/x4 should we call the AGPv2 routines directly ?
* Messy, as some AGPv3 cards can only do x4 as a minimum.
*/
/* PASS1: Count # of devs capable of AGPv3 mode. */
pci_for_each_dev(device) {
cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
if (cap_ptr != 0x00) {
pci_read_config_dword(device, cap_ptr, &scratch);
scratch &= (1<<20|1<<21|1<<22|1<<23);
scratch = scratch>>20;
/* AGP v3 capable ? */
if (scratch>=3) {
v3_devs++;
printk (KERN_INFO "AGP: Found AGPv3 capable device at %d:%d:%d\n",
device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
} else {
printk (KERN_INFO "AGP: Meh. version %x AGP device found.\n", scratch);
}
}
}
/* If not enough, go to AGP v2 setup */
if (v3_devs<2) {
printk (KERN_INFO "AGP: Only %d devices found, not enough, trying AGPv2\n", v3_devs);
return agp_generic_enable(mode);
} else {
printk (KERN_INFO "AGP: Enough AGPv3 devices found, setting up...\n");
}
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &command); printk(KERN_INFO PFX "Detected Opteron/Athlon64 on-CPU GART\n");
command = agp_collect_device_status(mode, command);
command |= 0x100;
pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_COMMAND, command);
agp_device_command(command, 1); bridge = agp_alloc_bridge();
} if (!bridge)
return -ENOMEM;
bridge->driver = &amd_8151_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
static int __init amd_8151_setup (struct pci_dev *pdev) /* Fill in the mode register */
{ pci_read_config_dword(pdev,
struct pci_dev *dev; bridge->capndx+PCI_AGP_STATUS,
int i=0; &bridge->mode);
agp_bridge->masks = amd_8151_masks;
agp_bridge->aperture_sizes = (void *) amd_8151_sizes;
agp_bridge->size_type = U32_APER_SIZE;
agp_bridge->num_aperture_sizes = 7;
agp_bridge->dev_private_data = NULL;
agp_bridge->needs_scratch_page = FALSE;
agp_bridge->configure = amd_8151_configure;
agp_bridge->fetch_size = amd_x86_64_fetch_size;
agp_bridge->cleanup = amd_8151_cleanup;
agp_bridge->tlb_flush = amd_x86_64_tlbflush;
agp_bridge->mask_memory = amd_8151_mask_memory;
agp_bridge->agp_enable = agp_x86_64_agp_enable;
agp_bridge->cache_flush = global_cache_flush;
agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
agp_bridge->insert_memory = x86_64_insert_memory;
agp_bridge->remove_memory = agp_generic_remove_memory;
agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
agp_bridge->free_by_type = agp_generic_free_by_type;
agp_bridge->agp_alloc_page = agp_generic_alloc_page;
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->suspend = agp_generic_suspend;
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
/* cache pci_devs of northbridges. */ /* cache pci_devs of northbridges. */
pci_for_each_dev(dev) { pci_for_each_dev(loop_dev) {
if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 && if (loop_dev->bus->number == 0 &&
(PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) { PCI_FUNC(loop_dev->devfn) == 3 &&
PCI_SLOT(loop_dev->devfn) >=24 &&
hammers[i++] = dev; PCI_SLOT(loop_dev->devfn) <=31) {
hammers[i++] = loop_dev;
nr_garts = i; nr_garts = i;
if (i==MAX_HAMMER_GARTS) if (i == MAX_HAMMER_GARTS)
return 0; goto out_free;
} }
} }
return 0; pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
out_free:
agp_put_bridge(bridge);
return -ENOMEM;
} }
static struct agp_driver amd_k8_agp_driver = { static void __devexit agp_amdk8_remove(struct pci_dev *pdev)
.owner = THIS_MODULE,
};
static int __init agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
u8 cap_ptr = 0; struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV;
printk (KERN_INFO PFX "Detected Opteron/Athlon64 on-CPU GART\n"); agp_remove_bridge(bridge);
agp_put_bridge(bridge);
agp_bridge->dev = dev;
agp_bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
amd_8151_setup(dev);
amd_k8_agp_driver.dev = dev;
agp_register_driver(&amd_k8_agp_driver);
return 0;
} }
static struct pci_device_id agp_amdk8_pci_table[] __initdata = { static struct pci_device_id agp_amdk8_pci_table[] __initdata = {
...@@ -371,25 +321,17 @@ static struct __initdata pci_driver agp_amdk8_pci_driver = { ...@@ -371,25 +321,17 @@ static struct __initdata pci_driver agp_amdk8_pci_driver = {
.name = "agpgart-amd-k8", .name = "agpgart-amd-k8",
.id_table = agp_amdk8_pci_table, .id_table = agp_amdk8_pci_table,
.probe = agp_amdk8_probe, .probe = agp_amdk8_probe,
.remove = agp_amdk8_remove,
}; };
/* Not static due to IOMMU code calling it early. */ /* Not static due to IOMMU code calling it early. */
int __init agp_amdk8_init(void) int __init agp_amdk8_init(void)
{ {
int ret_val; return pci_module_init(&agp_amdk8_pci_driver);
ret_val = pci_module_init(&agp_amdk8_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
agp_bridge->type = AMD_8151;
return ret_val;
} }
static void __exit agp_amdk8_cleanup(void) static void __exit agp_amdk8_cleanup(void)
{ {
agp_unregister_driver(&amd_k8_agp_driver);
pci_unregister_driver(&agp_amdk8_pci_driver); pci_unregister_driver(&agp_amdk8_pci_driver);
} }
......
...@@ -43,37 +43,54 @@ ...@@ -43,37 +43,54 @@
* past 0.99 at all due to some boolean logic error. */ * past 0.99 at all due to some boolean logic error. */
#define AGPGART_VERSION_MAJOR 0 #define AGPGART_VERSION_MAJOR 0
#define AGPGART_VERSION_MINOR 100 #define AGPGART_VERSION_MINOR 100
static struct agp_version agp_current_version =
{
.major = AGPGART_VERSION_MAJOR,
.minor = AGPGART_VERSION_MINOR,
};
static int agp_count=0;
struct agp_bridge_data agp_bridge_dummy = { .type = NOT_SUPPORTED }; struct agp_bridge_data agp_bridge_dummy = { .type = NOT_SUPPORTED };
struct agp_bridge_data *agp_bridge = &agp_bridge_dummy; struct agp_bridge_data *agp_bridge = &agp_bridge_dummy;
EXPORT_SYMBOL(agp_bridge);
/**
* agp_backend_acquire - attempt to acquire the agp backend.
*
* returns -EBUSY if agp is in use,
* returns 0 if the caller owns the agp backend
*/
int agp_backend_acquire(void) int agp_backend_acquire(void)
{ {
if (agp_bridge->type == NOT_SUPPORTED) if (agp_bridge->type == NOT_SUPPORTED)
return -EINVAL; return -EINVAL;
if (atomic_read(&agp_bridge->agp_in_use))
if (atomic_read(&agp_bridge->agp_in_use) != 0)
return -EBUSY; return -EBUSY;
atomic_inc(&agp_bridge->agp_in_use); atomic_inc(&agp_bridge->agp_in_use);
return 0; return 0;
} }
EXPORT_SYMBOL(agp_backend_acquire);
/**
* agp_backend_release - release the lock on the agp backend.
*
* The caller must insure that the graphics aperture translation table
* is read for use by another entity.
*
* (Ensure that all memory it bound is unbound.)
*/
void agp_backend_release(void) void agp_backend_release(void)
{ {
if (agp_bridge->type == NOT_SUPPORTED) if (agp_bridge->type != NOT_SUPPORTED)
return; atomic_dec(&agp_bridge->agp_in_use);
atomic_dec(&agp_bridge->agp_in_use);
} }
EXPORT_SYMBOL(agp_backend_release);
struct agp_max_table {
int mem;
int agp;
};
static struct agp_max_table maxes_table[9] = struct { int mem, agp; } maxes_table[] = {
{
{0, 0}, {0, 0},
{32, 4}, {32, 4},
{64, 28}, {64, 28},
...@@ -85,7 +102,7 @@ static struct agp_max_table maxes_table[9] = ...@@ -85,7 +102,7 @@ static struct agp_max_table maxes_table[9] =
{4096, 3932} {4096, 3932}
}; };
static int agp_find_max (void) static int agp_find_max(void)
{ {
long memory, index, result; long memory, index, result;
...@@ -105,48 +122,43 @@ static int agp_find_max (void) ...@@ -105,48 +122,43 @@ static int agp_find_max (void)
return result; return result;
} }
static struct agp_version agp_current_version =
{
.major = AGPGART_VERSION_MAJOR,
.minor = AGPGART_VERSION_MINOR,
};
static int agp_backend_initialize(struct pci_dev *dev) static int agp_backend_initialize(struct agp_bridge_data *bridge)
{ {
int size_value, rc, got_gatt=0, got_keylist=0; int size_value, rc, got_gatt=0, got_keylist=0;
agp_bridge->max_memory_agp = agp_find_max(); bridge->max_memory_agp = agp_find_max();
agp_bridge->version = &agp_current_version; bridge->version = &agp_current_version;
if (agp_bridge->needs_scratch_page == TRUE) { if (bridge->driver->needs_scratch_page) {
void *addr; void *addr = bridge->driver->agp_alloc_page();
addr = agp_bridge->agp_alloc_page();
if (addr == NULL) { if (!addr) {
printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
return -ENOMEM; return -ENOMEM;
} }
agp_bridge->scratch_page_real = virt_to_phys(addr);
agp_bridge->scratch_page =
agp_bridge->mask_memory(agp_bridge->scratch_page_real, 0);
}
size_value = agp_bridge->fetch_size(); bridge->scratch_page_real = virt_to_phys(addr);
bridge->scratch_page =
bridge->driver->mask_memory(bridge->scratch_page_real, 0);
}
size_value = bridge->driver->fetch_size();
if (size_value == 0) { if (size_value == 0) {
printk(KERN_ERR PFX "unable to determine aperture size.\n"); printk(KERN_ERR PFX "unable to determine aperture size.\n");
rc = -EINVAL; rc = -EINVAL;
goto err_out; goto err_out;
} }
if (agp_bridge->create_gatt_table()) { if (bridge->driver->create_gatt_table()) {
printk(KERN_ERR PFX "unable to get memory for graphics translation table.\n"); printk(KERN_ERR PFX
"unable to get memory for graphics translation table.\n");
rc = -ENOMEM; rc = -ENOMEM;
goto err_out; goto err_out;
} }
got_gatt = 1; got_gatt = 1;
agp_bridge->key_list = vmalloc(PAGE_SIZE * 4); bridge->key_list = vmalloc(PAGE_SIZE * 4);
if (agp_bridge->key_list == NULL) { if (bridge->key_list == NULL) {
printk(KERN_ERR PFX "error allocating memory for key lists.\n"); printk(KERN_ERR PFX "error allocating memory for key lists.\n");
rc = -ENOMEM; rc = -ENOMEM;
goto err_out; goto err_out;
...@@ -154,61 +166,62 @@ static int agp_backend_initialize(struct pci_dev *dev) ...@@ -154,61 +166,62 @@ static int agp_backend_initialize(struct pci_dev *dev)
got_keylist = 1; got_keylist = 1;
/* FIXME vmalloc'd memory not guaranteed contiguous */ /* FIXME vmalloc'd memory not guaranteed contiguous */
memset(agp_bridge->key_list, 0, PAGE_SIZE * 4); memset(bridge->key_list, 0, PAGE_SIZE * 4);
if (agp_bridge->configure()) { if (bridge->driver->configure()) {
printk(KERN_ERR PFX "error configuring host chipset.\n"); printk(KERN_ERR PFX "error configuring host chipset.\n");
rc = -EINVAL; rc = -EINVAL;
goto err_out; goto err_out;
} }
printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n", printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n",
size_value, agp_bridge->gart_bus_addr); size_value, bridge->gart_bus_addr);
return 0; return 0;
err_out: err_out:
if (agp_bridge->needs_scratch_page == TRUE) { if (bridge->driver->needs_scratch_page)
agp_bridge->agp_destroy_page(phys_to_virt(agp_bridge->scratch_page_real)); bridge->driver->agp_destroy_page(
} phys_to_virt(bridge->scratch_page_real));
if (got_gatt) if (got_gatt)
agp_bridge->free_gatt_table(); bridge->driver->free_gatt_table();
if (got_keylist) if (got_keylist) {
vfree(agp_bridge->key_list); vfree(bridge->key_list);
bridge->key_list = NULL;
}
return rc; return rc;
} }
/* cannot be __exit b/c as it could be called from __init code */ /* cannot be __exit b/c as it could be called from __init code */
static void agp_backend_cleanup(void) static void agp_backend_cleanup(struct agp_bridge_data *bridge)
{ {
if (agp_bridge->cleanup != NULL) if (bridge->driver->cleanup)
agp_bridge->cleanup(); bridge->driver->cleanup();
if (agp_bridge->free_gatt_table != NULL) if (bridge->driver->free_gatt_table)
agp_bridge->free_gatt_table(); bridge->driver->free_gatt_table();
if (agp_bridge->key_list) if (bridge->key_list) {
vfree(agp_bridge->key_list); vfree(bridge->key_list);
bridge->key_list = NULL;
if ((agp_bridge->agp_destroy_page!=NULL) && }
(agp_bridge->needs_scratch_page == TRUE))
agp_bridge->agp_destroy_page(phys_to_virt(agp_bridge->scratch_page_real)); if (bridge->driver->agp_destroy_page &&
bridge->driver->needs_scratch_page)
bridge->driver->agp_destroy_page(
phys_to_virt(bridge->scratch_page_real));
} }
static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data) static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data)
{ {
switch(rq) switch(rq) {
{
case PM_SUSPEND: case PM_SUSPEND:
return agp_bridge->suspend(); return agp_bridge->driver->suspend();
case PM_RESUME: case PM_RESUME:
agp_bridge->resume(); agp_bridge->driver->resume();
return 0; return 0;
} }
return 0; return 0;
} }
extern int agp_frontend_initialize(void);
extern void agp_frontend_cleanup(void);
static const drm_agp_t drm_agp = { static const drm_agp_t drm_agp = {
&agp_free_memory, &agp_free_memory,
...@@ -221,78 +234,81 @@ static const drm_agp_t drm_agp = { ...@@ -221,78 +234,81 @@ static const drm_agp_t drm_agp = {
&agp_copy_info &agp_copy_info
}; };
static int agp_count=0; /* XXX Kludge alert: agpgart isn't ready for multiple bridges yet */
struct agp_bridge_data *agp_alloc_bridge(void)
{
return agp_bridge;
}
EXPORT_SYMBOL(agp_alloc_bridge);
int agp_register_driver (struct agp_driver *drv) void agp_put_bridge(struct agp_bridge_data *bridge)
{ {
int ret_val; }
EXPORT_SYMBOL(agp_put_bridge);
int agp_add_bridge(struct agp_bridge_data *bridge)
{
int error;
if (drv->dev == NULL) { if (!bridge->dev) {
printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n"); printk(KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
return -EINVAL; return -EINVAL;
} }
if (agp_count==1) { if (agp_count) {
printk (KERN_DEBUG PFX "Only one agpgart device currently supported.\n"); printk(KERN_DEBUG PFX
"Only one agpgart device currently supported.\n");
return -ENODEV; return -ENODEV;
} }
/* Grab reference on the chipset driver. */ /* Grab reference on the chipset driver. */
if (!try_module_get(drv->owner)) if (!try_module_get(bridge->driver->owner))
return -EINVAL; return -EINVAL;
ret_val = agp_backend_initialize(drv->dev); bridge->type = SUPPORTED;
if (ret_val)
error = agp_backend_initialize(agp_bridge);
if (error)
goto err_out; goto err_out;
ret_val = agp_frontend_initialize(); error = agp_frontend_initialize();
if (ret_val) if (error)
goto frontend_err; goto frontend_err;
/* FIXME: What to do with this? */ /* FIXME: What to do with this? */
inter_module_register("drm_agp", THIS_MODULE, &drm_agp); inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge->dev), agp_power); pm_register(PM_PCI_DEV, PM_PCI_ID(bridge->dev), agp_power);
agp_count++; agp_count++;
return 0; return 0;
frontend_err: frontend_err:
agp_backend_cleanup(); agp_backend_cleanup(agp_bridge);
err_out: err_out:
agp_bridge->type = NOT_SUPPORTED; bridge->type = NOT_SUPPORTED;
module_put(drv->owner); module_put(bridge->driver->owner);
drv->dev = NULL; return error;
return ret_val;
} }
EXPORT_SYMBOL_GPL(agp_add_bridge);
int agp_unregister_driver(struct agp_driver *drv)
{
if (drv->dev==NULL)
return -ENODEV;
agp_bridge->type = NOT_SUPPORTED; void agp_remove_bridge(struct agp_bridge_data *bridge)
{
bridge->type = NOT_SUPPORTED;
pm_unregister_all(agp_power); pm_unregister_all(agp_power);
agp_frontend_cleanup(); agp_frontend_cleanup();
agp_backend_cleanup(); agp_backend_cleanup(bridge);
inter_module_unregister("drm_agp"); inter_module_unregister("drm_agp");
agp_count--; agp_count--;
module_put(drv->owner); module_put(bridge->driver->owner);
return 0;
} }
EXPORT_SYMBOL_GPL(agp_remove_bridge);
int __init agp_init(void) static int __init agp_init(void)
{ {
static int already_initialised=0;
if (already_initialised!=0)
return 0;
already_initialised = 1;
memset(agp_bridge, 0, sizeof(struct agp_bridge_data));
agp_bridge->type = NOT_SUPPORTED;
printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n", printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n",
AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR); AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
return 0; return 0;
...@@ -300,19 +316,13 @@ int __init agp_init(void) ...@@ -300,19 +316,13 @@ int __init agp_init(void)
void __exit agp_exit(void) void __exit agp_exit(void)
{ {
if (agp_count!=0)
BUG();
} }
#ifndef CONFIG_GART_IOMMU
module_init(agp_init);
module_exit(agp_exit);
#endif
EXPORT_SYMBOL(agp_backend_acquire);
EXPORT_SYMBOL(agp_backend_release);
EXPORT_SYMBOL_GPL(agp_register_driver);
EXPORT_SYMBOL_GPL(agp_unregister_driver);
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION("AGP GART driver");
MODULE_LICENSE("GPL and additional rights"); MODULE_LICENSE("GPL and additional rights");
module_init(agp_init);
module_exit(agp_exit);
...@@ -53,11 +53,12 @@ static agp_memory *agp_find_mem_by_key(int key) ...@@ -53,11 +53,12 @@ static agp_memory *agp_find_mem_by_key(int key)
while (curr != NULL) { while (curr != NULL) {
if (curr->key == key) if (curr->key == key)
return curr; break;
curr = curr->next; curr = curr->next;
} }
return NULL; DBG("key=%d -> mem=%p", key, curr);
return curr;
} }
static void agp_remove_from_pool(agp_memory * temp) static void agp_remove_from_pool(agp_memory * temp)
...@@ -67,6 +68,7 @@ static void agp_remove_from_pool(agp_memory * temp) ...@@ -67,6 +68,7 @@ static void agp_remove_from_pool(agp_memory * temp)
/* Check to see if this is even in the memory pool */ /* Check to see if this is even in the memory pool */
DBG("mem=%p", temp);
if (agp_find_mem_by_key(temp->key) != NULL) { if (agp_find_mem_by_key(temp->key) != NULL) {
next = temp->next; next = temp->next;
prev = temp->prev; prev = temp->prev;
...@@ -92,11 +94,12 @@ static void agp_remove_from_pool(agp_memory * temp) ...@@ -92,11 +94,12 @@ static void agp_remove_from_pool(agp_memory * temp)
* to each auth'ed client. * to each auth'ed client.
*/ */
static agp_segment_priv *agp_find_seg_in_client(const agp_client * client, static struct
agp_segment_priv *agp_find_seg_in_client(const struct agp_client *client,
unsigned long offset, unsigned long offset,
int size, pgprot_t page_prot) int size, pgprot_t page_prot)
{ {
agp_segment_priv *seg; struct agp_segment_priv *seg;
int num_segments, i; int num_segments, i;
off_t pg_start; off_t pg_start;
size_t pg_count; size_t pg_count;
...@@ -117,25 +120,32 @@ static agp_segment_priv *agp_find_seg_in_client(const agp_client * client, ...@@ -117,25 +120,32 @@ static agp_segment_priv *agp_find_seg_in_client(const agp_client * client,
return NULL; return NULL;
} }
static void agp_remove_seg_from_client(agp_client * client) static void agp_remove_seg_from_client(struct agp_client *client)
{ {
DBG("client=%p", client);
if (client->segments != NULL) { if (client->segments != NULL) {
if (*(client->segments) != NULL) if (*(client->segments) != NULL) {
DBG("Freeing %p from client %p", *(client->segments), client);
kfree(*(client->segments)); kfree(*(client->segments));
}
DBG("Freeing %p from client %p", client->segments, client);
kfree(client->segments); kfree(client->segments);
client->segments = NULL;
} }
} }
static void agp_add_seg_to_client(agp_client * client, static void agp_add_seg_to_client(struct agp_client *client,
agp_segment_priv ** seg, int num_segments) struct agp_segment_priv ** seg, int num_segments)
{ {
agp_segment_priv **prev_seg; struct agp_segment_priv **prev_seg;
prev_seg = client->segments; prev_seg = client->segments;
if (prev_seg != NULL) if (prev_seg != NULL)
agp_remove_seg_from_client(client); agp_remove_seg_from_client(client);
DBG("Adding seg %p (%d segments) to client %p", seg, num_segments, client);
client->num_segments = num_segments; client->num_segments = num_segments;
client->segments = seg; client->segments = seg;
} }
...@@ -171,19 +181,20 @@ static pgprot_t agp_convert_mmap_flags(int prot) ...@@ -171,19 +181,20 @@ static pgprot_t agp_convert_mmap_flags(int prot)
return temp; return temp;
} }
static int agp_create_segment(agp_client * client, agp_region * region) static int agp_create_segment(struct agp_client *client, struct agp_region *region)
{ {
agp_segment_priv **ret_seg; struct agp_segment_priv **ret_seg;
agp_segment_priv *seg; struct agp_segment_priv *seg;
agp_segment *user_seg; struct agp_segment *user_seg;
size_t i; size_t i;
seg = kmalloc((sizeof(agp_segment_priv) * region->seg_count), GFP_KERNEL); seg = kmalloc((sizeof(struct agp_segment_priv) * region->seg_count), GFP_KERNEL);
if (seg == NULL) { if (seg == NULL) {
kfree(region->seg_list); kfree(region->seg_list);
region->seg_list = NULL;
return -ENOMEM; return -ENOMEM;
} }
memset(seg, 0, (sizeof(agp_segment_priv) * region->seg_count)); memset(seg, 0, (sizeof(struct agp_segment_priv) * region->seg_count));
user_seg = region->seg_list; user_seg = region->seg_list;
for (i = 0; i < region->seg_count; i++) { for (i = 0; i < region->seg_count; i++) {
...@@ -191,14 +202,15 @@ static int agp_create_segment(agp_client * client, agp_region * region) ...@@ -191,14 +202,15 @@ static int agp_create_segment(agp_client * client, agp_region * region)
seg[i].pg_count = user_seg[i].pg_count; seg[i].pg_count = user_seg[i].pg_count;
seg[i].prot = agp_convert_mmap_flags(user_seg[i].prot); seg[i].prot = agp_convert_mmap_flags(user_seg[i].prot);
} }
kfree(region->seg_list);
region->seg_list = NULL;
ret_seg = kmalloc(sizeof(void *), GFP_KERNEL); ret_seg = kmalloc(sizeof(void *), GFP_KERNEL);
if (ret_seg == NULL) { if (ret_seg == NULL) {
kfree(region->seg_list);
kfree(seg); kfree(seg);
return -ENOMEM; return -ENOMEM;
} }
*ret_seg = seg; *ret_seg = seg;
kfree(region->seg_list);
agp_add_seg_to_client(client, ret_seg, region->seg_count); agp_add_seg_to_client(client, ret_seg, region->seg_count);
return 0; return 0;
} }
...@@ -222,9 +234,9 @@ static void agp_insert_into_pool(agp_memory * temp) ...@@ -222,9 +234,9 @@ static void agp_insert_into_pool(agp_memory * temp)
/* File private list routines */ /* File private list routines */
agp_file_private *agp_find_private(pid_t pid) struct agp_file_private *agp_find_private(pid_t pid)
{ {
agp_file_private *curr; struct agp_file_private *curr;
curr = agp_fe.file_priv_list; curr = agp_fe.file_priv_list;
...@@ -237,9 +249,9 @@ agp_file_private *agp_find_private(pid_t pid) ...@@ -237,9 +249,9 @@ agp_file_private *agp_find_private(pid_t pid)
return NULL; return NULL;
} }
void agp_insert_file_private(agp_file_private * priv) void agp_insert_file_private(struct agp_file_private * priv)
{ {
agp_file_private *prev; struct agp_file_private *prev;
prev = agp_fe.file_priv_list; prev = agp_fe.file_priv_list;
...@@ -249,10 +261,10 @@ void agp_insert_file_private(agp_file_private * priv) ...@@ -249,10 +261,10 @@ void agp_insert_file_private(agp_file_private * priv)
agp_fe.file_priv_list = priv; agp_fe.file_priv_list = priv;
} }
void agp_remove_file_private(agp_file_private * priv) void agp_remove_file_private(struct agp_file_private * priv)
{ {
agp_file_private *next; struct agp_file_private *next;
agp_file_private *prev; struct agp_file_private *prev;
next = priv->next; next = priv->next;
prev = priv->prev; prev = priv->prev;
...@@ -301,9 +313,9 @@ static agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type) ...@@ -301,9 +313,9 @@ static agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
* controllers * controllers
*/ */
static agp_controller *agp_find_controller_by_pid(pid_t id) static struct agp_controller *agp_find_controller_by_pid(pid_t id)
{ {
agp_controller *controller; struct agp_controller *controller;
controller = agp_fe.controllers; controller = agp_fe.controllers;
...@@ -316,24 +328,24 @@ static agp_controller *agp_find_controller_by_pid(pid_t id) ...@@ -316,24 +328,24 @@ static agp_controller *agp_find_controller_by_pid(pid_t id)
return NULL; return NULL;
} }
static agp_controller *agp_create_controller(pid_t id) static struct agp_controller *agp_create_controller(pid_t id)
{ {
agp_controller *controller; struct agp_controller *controller;
controller = kmalloc(sizeof(agp_controller), GFP_KERNEL); controller = kmalloc(sizeof(struct agp_controller), GFP_KERNEL);
if (controller == NULL) if (controller == NULL)
return NULL; return NULL;
memset(controller, 0, sizeof(agp_controller)); memset(controller, 0, sizeof(struct agp_controller));
controller->pid = id; controller->pid = id;
return controller; return controller;
} }
static int agp_insert_controller(agp_controller * controller) static int agp_insert_controller(struct agp_controller *controller)
{ {
agp_controller *prev_controller; struct agp_controller *prev_controller;
prev_controller = agp_fe.controllers; prev_controller = agp_fe.controllers;
controller->next = prev_controller; controller->next = prev_controller;
...@@ -346,15 +358,15 @@ static int agp_insert_controller(agp_controller * controller) ...@@ -346,15 +358,15 @@ static int agp_insert_controller(agp_controller * controller)
return 0; return 0;
} }
static void agp_remove_all_clients(agp_controller * controller) static void agp_remove_all_clients(struct agp_controller *controller)
{ {
agp_client *client; struct agp_client *client;
agp_client *temp; struct agp_client *temp;
client = controller->clients; client = controller->clients;
while (client) { while (client) {
agp_file_private *priv; struct agp_file_private *priv;
temp = client; temp = client;
agp_remove_seg_from_client(temp); agp_remove_seg_from_client(temp);
...@@ -369,7 +381,7 @@ static void agp_remove_all_clients(agp_controller * controller) ...@@ -369,7 +381,7 @@ static void agp_remove_all_clients(agp_controller * controller)
} }
} }
static void agp_remove_all_memory(agp_controller * controller) static void agp_remove_all_memory(struct agp_controller *controller)
{ {
agp_memory *memory; agp_memory *memory;
agp_memory *temp; agp_memory *temp;
...@@ -383,10 +395,10 @@ static void agp_remove_all_memory(agp_controller * controller) ...@@ -383,10 +395,10 @@ static void agp_remove_all_memory(agp_controller * controller)
} }
} }
static int agp_remove_controller(agp_controller * controller) static int agp_remove_controller(struct agp_controller *controller)
{ {
agp_controller *prev_controller; struct agp_controller *prev_controller;
agp_controller *next_controller; struct agp_controller *next_controller;
prev_controller = controller->prev; prev_controller = controller->prev;
next_controller = controller->next; next_controller = controller->next;
...@@ -415,14 +427,14 @@ static int agp_remove_controller(agp_controller * controller) ...@@ -415,14 +427,14 @@ static int agp_remove_controller(agp_controller * controller)
return 0; return 0;
} }
static void agp_controller_make_current(agp_controller * controller) static void agp_controller_make_current(struct agp_controller *controller)
{ {
agp_client *clients; struct agp_client *clients;
clients = controller->clients; clients = controller->clients;
while (clients != NULL) { while (clients != NULL) {
agp_file_private *priv; struct agp_file_private *priv;
priv = agp_find_private(clients->pid); priv = agp_find_private(clients->pid);
...@@ -436,16 +448,16 @@ static void agp_controller_make_current(agp_controller * controller) ...@@ -436,16 +448,16 @@ static void agp_controller_make_current(agp_controller * controller)
agp_fe.current_controller = controller; agp_fe.current_controller = controller;
} }
static void agp_controller_release_current(agp_controller * controller, static void agp_controller_release_current(struct agp_controller *controller,
agp_file_private * controller_priv) struct agp_file_private *controller_priv)
{ {
agp_client *clients; struct agp_client *clients;
clear_bit(AGP_FF_IS_VALID, &controller_priv->access_flags); clear_bit(AGP_FF_IS_VALID, &controller_priv->access_flags);
clients = controller->clients; clients = controller->clients;
while (clients != NULL) { while (clients != NULL) {
agp_file_private *priv; struct agp_file_private *priv;
priv = agp_find_private(clients->pid); priv = agp_find_private(clients->pid);
...@@ -465,10 +477,10 @@ static void agp_controller_release_current(agp_controller * controller, ...@@ -465,10 +477,10 @@ static void agp_controller_release_current(agp_controller * controller,
* These routines are for managing the list of auth'ed clients. * These routines are for managing the list of auth'ed clients.
*/ */
static agp_client *agp_find_client_in_controller(agp_controller * controller, static struct agp_client
pid_t id) *agp_find_client_in_controller(struct agp_controller *controller, pid_t id)
{ {
agp_client *client; struct agp_client *client;
if (controller == NULL) if (controller == NULL)
return NULL; return NULL;
...@@ -484,9 +496,9 @@ static agp_client *agp_find_client_in_controller(agp_controller * controller, ...@@ -484,9 +496,9 @@ static agp_client *agp_find_client_in_controller(agp_controller * controller,
return NULL; return NULL;
} }
static agp_controller *agp_find_controller_for_client(pid_t id) static struct agp_controller *agp_find_controller_for_client(pid_t id)
{ {
agp_controller *controller; struct agp_controller *controller;
controller = agp_fe.controllers; controller = agp_fe.controllers;
...@@ -499,9 +511,9 @@ static agp_controller *agp_find_controller_for_client(pid_t id) ...@@ -499,9 +511,9 @@ static agp_controller *agp_find_controller_for_client(pid_t id)
return NULL; return NULL;
} }
static agp_client *agp_find_client_by_pid(pid_t id) static struct agp_client *agp_find_client_by_pid(pid_t id)
{ {
agp_client *temp; struct agp_client *temp;
if (agp_fe.current_controller == NULL) if (agp_fe.current_controller == NULL)
return NULL; return NULL;
...@@ -510,9 +522,9 @@ static agp_client *agp_find_client_by_pid(pid_t id) ...@@ -510,9 +522,9 @@ static agp_client *agp_find_client_by_pid(pid_t id)
return temp; return temp;
} }
static void agp_insert_client(agp_client * client) static void agp_insert_client(struct agp_client *client)
{ {
agp_client *prev_client; struct agp_client *prev_client;
prev_client = agp_fe.current_controller->clients; prev_client = agp_fe.current_controller->clients;
client->next = prev_client; client->next = prev_client;
...@@ -524,16 +536,16 @@ static void agp_insert_client(agp_client * client) ...@@ -524,16 +536,16 @@ static void agp_insert_client(agp_client * client)
agp_fe.current_controller->num_clients++; agp_fe.current_controller->num_clients++;
} }
static agp_client *agp_create_client(pid_t id) static struct agp_client *agp_create_client(pid_t id)
{ {
agp_client *new_client; struct agp_client *new_client;
new_client = kmalloc(sizeof(agp_client), GFP_KERNEL); new_client = kmalloc(sizeof(struct agp_client), GFP_KERNEL);
if (new_client == NULL) if (new_client == NULL)
return NULL; return NULL;
memset(new_client, 0, sizeof(agp_client)); memset(new_client, 0, sizeof(struct agp_client));
new_client->pid = id; new_client->pid = id;
agp_insert_client(new_client); agp_insert_client(new_client);
return new_client; return new_client;
...@@ -541,10 +553,10 @@ static agp_client *agp_create_client(pid_t id) ...@@ -541,10 +553,10 @@ static agp_client *agp_create_client(pid_t id)
static int agp_remove_client(pid_t id) static int agp_remove_client(pid_t id)
{ {
agp_client *client; struct agp_client *client;
agp_client *prev_client; struct agp_client *prev_client;
agp_client *next_client; struct agp_client *next_client;
agp_controller *controller; struct agp_controller *controller;
controller = agp_find_controller_for_client(id); controller = agp_find_controller_for_client(id);
if (controller == NULL) if (controller == NULL)
...@@ -582,11 +594,11 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -582,11 +594,11 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
{ {
unsigned int size, current_size; unsigned int size, current_size;
unsigned long offset; unsigned long offset;
agp_client *client; struct agp_client *client;
agp_file_private *priv = (agp_file_private *) file->private_data; struct agp_file_private *priv = file->private_data;
agp_kern_info kerninfo; agp_kern_info kerninfo;
AGP_LOCK(); down(&(agp_fe.agp_mutex));
if (agp_fe.backend_acquired != TRUE) if (agp_fe.backend_acquired != TRUE)
goto out_eperm; goto out_eperm;
...@@ -599,6 +611,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -599,6 +611,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
current_size = kerninfo.aper_size; current_size = kerninfo.aper_size;
current_size = current_size * 0x100000; current_size = current_size * 0x100000;
offset = vma->vm_pgoff << PAGE_SHIFT; offset = vma->vm_pgoff << PAGE_SHIFT;
DBG("%lx:%lx", offset, offset+size);
if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) { if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {
if ((size + offset) > current_size) if ((size + offset) > current_size)
...@@ -612,6 +625,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -612,6 +625,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot)) if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot))
goto out_inval; goto out_inval;
DBG("client vm_ops=%p", kerninfo.vm_ops);
if (kerninfo.vm_ops) { if (kerninfo.vm_ops) {
vma->vm_ops = kerninfo.vm_ops; vma->vm_ops = kerninfo.vm_ops;
} else if (remap_page_range(vma, vma->vm_start, } else if (remap_page_range(vma, vma->vm_start,
...@@ -619,7 +633,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -619,7 +633,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
size, vma->vm_page_prot)) { size, vma->vm_page_prot)) {
goto out_again; goto out_again;
} }
AGP_UNLOCK(); up(&(agp_fe.agp_mutex));
return 0; return 0;
} }
...@@ -627,6 +641,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -627,6 +641,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
if (size != current_size) if (size != current_size)
goto out_inval; goto out_inval;
DBG("controller vm_ops=%p", kerninfo.vm_ops);
if (kerninfo.vm_ops) { if (kerninfo.vm_ops) {
vma->vm_ops = kerninfo.vm_ops; vma->vm_ops = kerninfo.vm_ops;
} else if (remap_page_range(vma, vma->vm_start, } else if (remap_page_range(vma, vma->vm_start,
...@@ -634,68 +649,71 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -634,68 +649,71 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
size, vma->vm_page_prot)) { size, vma->vm_page_prot)) {
goto out_again; goto out_again;
} }
AGP_UNLOCK(); up(&(agp_fe.agp_mutex));
return 0; return 0;
} }
out_eperm: out_eperm:
AGP_UNLOCK(); up(&(agp_fe.agp_mutex));
return -EPERM; return -EPERM;
out_inval: out_inval:
AGP_UNLOCK(); up(&(agp_fe.agp_mutex));
return -EINVAL; return -EINVAL;
out_again: out_again:
AGP_UNLOCK(); up(&(agp_fe.agp_mutex));
return -EAGAIN; return -EAGAIN;
} }
static int agp_release(struct inode *inode, struct file *file) static int agp_release(struct inode *inode, struct file *file)
{ {
agp_file_private *priv = (agp_file_private *) file->private_data; struct agp_file_private *priv = file->private_data;
AGP_LOCK(); down(&(agp_fe.agp_mutex));
DBG("priv=%p", priv);
if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) { if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) {
agp_controller *controller; struct agp_controller *controller;
controller = agp_find_controller_by_pid(priv->my_pid); controller = agp_find_controller_by_pid(priv->my_pid);
if (controller != NULL) { if (controller != NULL) {
if (controller == agp_fe.current_controller) { if (controller == agp_fe.current_controller)
agp_controller_release_current(controller, agp_controller_release_current(controller, priv);
priv);
}
agp_remove_controller(controller); agp_remove_controller(controller);
controller = NULL;
} }
} }
if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) {
if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags))
agp_remove_client(priv->my_pid); agp_remove_client(priv->my_pid);
}
agp_remove_file_private(priv); agp_remove_file_private(priv);
kfree(priv); kfree(priv);
AGP_UNLOCK(); file->private_data = NULL;
up(&(agp_fe.agp_mutex));
return 0; return 0;
} }
static int agp_open(struct inode *inode, struct file *file) static int agp_open(struct inode *inode, struct file *file)
{ {
int minor = minor(inode->i_rdev); int minor = minor(inode->i_rdev);
agp_file_private *priv; struct agp_file_private *priv;
agp_client *client; struct agp_client *client;
int rc = -ENXIO; int rc = -ENXIO;
AGP_LOCK(); down(&(agp_fe.agp_mutex));
if (minor != AGPGART_MINOR) if (minor != AGPGART_MINOR)
goto err_out; goto err_out;
priv = kmalloc(sizeof(agp_file_private), GFP_KERNEL); priv = kmalloc(sizeof(struct agp_file_private), GFP_KERNEL);
if (priv == NULL) if (priv == NULL)
goto err_out_nomem; goto err_out_nomem;
memset(priv, 0, sizeof(agp_file_private)); memset(priv, 0, sizeof(struct agp_file_private));
set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags); set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
priv->my_pid = current->pid; priv->my_pid = current->pid;
...@@ -711,13 +729,14 @@ static int agp_open(struct inode *inode, struct file *file) ...@@ -711,13 +729,14 @@ static int agp_open(struct inode *inode, struct file *file)
} }
file->private_data = (void *) priv; file->private_data = (void *) priv;
agp_insert_file_private(priv); agp_insert_file_private(priv);
AGP_UNLOCK(); DBG("private=%p, client=%p", priv, client);
up(&(agp_fe.agp_mutex));
return 0; return 0;
err_out_nomem: err_out_nomem:
rc = -ENOMEM; rc = -ENOMEM;
err_out: err_out:
AGP_UNLOCK(); up(&(agp_fe.agp_mutex));
return rc; return rc;
} }
...@@ -734,9 +753,9 @@ static ssize_t agp_write(struct file *file, const char *buf, ...@@ -734,9 +753,9 @@ static ssize_t agp_write(struct file *file, const char *buf,
return -EINVAL; return -EINVAL;
} }
static int agpioc_info_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_info_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
agp_info userinfo; struct agp_info userinfo;
agp_kern_info kerninfo; agp_kern_info kerninfo;
agp_copy_info(&kerninfo); agp_copy_info(&kerninfo);
...@@ -751,17 +770,19 @@ static int agpioc_info_wrap(agp_file_private * priv, unsigned long arg) ...@@ -751,17 +770,19 @@ static int agpioc_info_wrap(agp_file_private * priv, unsigned long arg)
userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory; userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
userinfo.pg_used = kerninfo.current_memory; userinfo.pg_used = kerninfo.current_memory;
if (copy_to_user((void *) arg, &userinfo, sizeof(agp_info))) if (copy_to_user((void *) arg, &userinfo, sizeof(struct agp_info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
static int agpioc_acquire_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_acquire_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
int ret; int ret;
struct agp_controller *controller;
DBG("");
agp_controller *controller;
if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags))) if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags)))
return -EPERM; return -EPERM;
...@@ -795,33 +816,36 @@ static int agpioc_acquire_wrap(agp_file_private * priv, unsigned long arg) ...@@ -795,33 +816,36 @@ static int agpioc_acquire_wrap(agp_file_private * priv, unsigned long arg)
return 0; return 0;
} }
static int agpioc_release_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_release_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
DBG("");
agp_controller_release_current(agp_fe.current_controller, priv); agp_controller_release_current(agp_fe.current_controller, priv);
return 0; return 0;
} }
static int agpioc_setup_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_setup_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
agp_setup mode; struct agp_setup mode;
if (copy_from_user(&mode, (void *) arg, sizeof(agp_setup))) { DBG("");
if (copy_from_user(&mode, (void *) arg, sizeof(struct agp_setup)))
return -EFAULT; return -EFAULT;
}
agp_enable(mode.agp_mode); agp_enable(mode.agp_mode);
return 0; return 0;
} }
static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_reserve_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
agp_region reserve; struct agp_region reserve;
agp_client *client; struct agp_client *client;
agp_file_private *client_priv; struct agp_file_private *client_priv;
if (copy_from_user(&reserve, (void *) arg, sizeof(agp_region))) DBG("");
if (copy_from_user(&reserve, (void *) arg, sizeof(struct agp_region)))
return -EFAULT; return -EFAULT;
if ((unsigned) reserve.seg_count >= ~0U/sizeof(agp_segment)) if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
return -EFAULT; return -EFAULT;
client = agp_find_client_by_pid(reserve.pid); client = agp_find_client_by_pid(reserve.pid);
...@@ -831,10 +855,8 @@ static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg) ...@@ -831,10 +855,8 @@ static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg)
client_priv = agp_find_private(reserve.pid); client_priv = agp_find_private(reserve.pid);
if (client_priv != NULL) { if (client_priv != NULL) {
set_bit(AGP_FF_IS_CLIENT, set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
&client_priv->access_flags); set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
set_bit(AGP_FF_IS_VALID,
&client_priv->access_flags);
} }
if (client == NULL) { if (client == NULL) {
/* client is already removed */ /* client is already removed */
...@@ -842,19 +864,19 @@ static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg) ...@@ -842,19 +864,19 @@ static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg)
} }
return agp_remove_client(reserve.pid); return agp_remove_client(reserve.pid);
} else { } else {
agp_segment *segment; struct agp_segment *segment;
if (reserve.seg_count >= 16384) if (reserve.seg_count >= 16384)
return -EINVAL; return -EINVAL;
segment = kmalloc((sizeof(agp_segment) * reserve.seg_count), segment = kmalloc((sizeof(struct agp_segment) * reserve.seg_count),
GFP_KERNEL); GFP_KERNEL);
if (segment == NULL) if (segment == NULL)
return -ENOMEM; return -ENOMEM;
if (copy_from_user(segment, (void *) reserve.seg_list, if (copy_from_user(segment, (void *) reserve.seg_list,
sizeof(agp_segment) * reserve.seg_count)) { sizeof(struct agp_segment) * reserve.seg_count)) {
kfree(segment); kfree(segment);
return -EFAULT; return -EFAULT;
} }
...@@ -871,32 +893,30 @@ static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg) ...@@ -871,32 +893,30 @@ static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg)
client_priv = agp_find_private(reserve.pid); client_priv = agp_find_private(reserve.pid);
if (client_priv != NULL) { if (client_priv != NULL) {
set_bit(AGP_FF_IS_CLIENT, set_bit(AGP_FF_IS_CLIENT, &client_priv->access_flags);
&client_priv->access_flags); set_bit(AGP_FF_IS_VALID, &client_priv->access_flags);
set_bit(AGP_FF_IS_VALID,
&client_priv->access_flags);
} }
return agp_create_segment(client, &reserve);
} else {
return agp_create_segment(client, &reserve);
} }
return agp_create_segment(client, &reserve);
} }
/* Will never really happen */ /* Will never really happen */
return -EINVAL; return -EINVAL;
} }
static int agpioc_protect_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_protect_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
DBG("");
/* This function is not currently implemented */ /* This function is not currently implemented */
return -EINVAL; return -EINVAL;
} }
static int agpioc_allocate_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_allocate_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
agp_memory *memory; agp_memory *memory;
agp_allocate alloc; struct agp_allocate alloc;
if (copy_from_user(&alloc, (void *) arg, sizeof(agp_allocate))) DBG("");
if (copy_from_user(&alloc, (void *) arg, sizeof(struct agp_allocate)))
return -EFAULT; return -EFAULT;
memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type); memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
...@@ -907,17 +927,18 @@ static int agpioc_allocate_wrap(agp_file_private * priv, unsigned long arg) ...@@ -907,17 +927,18 @@ static int agpioc_allocate_wrap(agp_file_private * priv, unsigned long arg)
alloc.key = memory->key; alloc.key = memory->key;
alloc.physical = memory->physical; alloc.physical = memory->physical;
if (copy_to_user((void *) arg, &alloc, sizeof(agp_allocate))) { if (copy_to_user((void *) arg, &alloc, sizeof(struct agp_allocate))) {
agp_free_memory_wrap(memory); agp_free_memory_wrap(memory);
return -EFAULT; return -EFAULT;
} }
return 0; return 0;
} }
static int agpioc_deallocate_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_deallocate_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
agp_memory *memory; agp_memory *memory;
DBG("");
memory = agp_find_mem_by_key((int) arg); memory = agp_find_mem_by_key((int) arg);
if (memory == NULL) if (memory == NULL)
...@@ -927,12 +948,13 @@ static int agpioc_deallocate_wrap(agp_file_private * priv, unsigned long arg) ...@@ -927,12 +948,13 @@ static int agpioc_deallocate_wrap(agp_file_private * priv, unsigned long arg)
return 0; return 0;
} }
static int agpioc_bind_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_bind_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
agp_bind bind_info; struct agp_bind bind_info;
agp_memory *memory; agp_memory *memory;
if (copy_from_user(&bind_info, (void *) arg, sizeof(agp_bind))) DBG("");
if (copy_from_user(&bind_info, (void *) arg, sizeof(struct agp_bind)))
return -EFAULT; return -EFAULT;
memory = agp_find_mem_by_key(bind_info.key); memory = agp_find_mem_by_key(bind_info.key);
...@@ -943,12 +965,13 @@ static int agpioc_bind_wrap(agp_file_private * priv, unsigned long arg) ...@@ -943,12 +965,13 @@ static int agpioc_bind_wrap(agp_file_private * priv, unsigned long arg)
return agp_bind_memory(memory, bind_info.pg_start); return agp_bind_memory(memory, bind_info.pg_start);
} }
static int agpioc_unbind_wrap(agp_file_private * priv, unsigned long arg) static int agpioc_unbind_wrap(struct agp_file_private *priv, unsigned long arg)
{ {
agp_memory *memory; agp_memory *memory;
agp_unbind unbind; struct agp_unbind unbind;
if (copy_from_user(&unbind, (void *) arg, sizeof(agp_unbind))) DBG("");
if (copy_from_user(&unbind, (void *) arg, sizeof(struct agp_unbind)))
return -EFAULT; return -EFAULT;
memory = agp_find_mem_by_key(unbind.key); memory = agp_find_mem_by_key(unbind.key);
...@@ -962,10 +985,11 @@ static int agpioc_unbind_wrap(agp_file_private * priv, unsigned long arg) ...@@ -962,10 +985,11 @@ static int agpioc_unbind_wrap(agp_file_private * priv, unsigned long arg)
static int agp_ioctl(struct inode *inode, struct file *file, static int agp_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
agp_file_private *curr_priv = (agp_file_private *) file->private_data; struct agp_file_private *curr_priv = file->private_data;
int ret_val = -ENOTTY; int ret_val = -ENOTTY;
AGP_LOCK(); DBG("priv=%p, cmd=%x", curr_priv, cmd);
down(&(agp_fe.agp_mutex));
if ((agp_fe.current_controller == NULL) && if ((agp_fe.current_controller == NULL) &&
(cmd != AGPIOC_ACQUIRE)) { (cmd != AGPIOC_ACQUIRE)) {
...@@ -1034,7 +1058,8 @@ static int agp_ioctl(struct inode *inode, struct file *file, ...@@ -1034,7 +1058,8 @@ static int agp_ioctl(struct inode *inode, struct file *file,
} }
ioctl_out: ioctl_out:
AGP_UNLOCK(); DBG("ioctl returns %d\n", ret_val);
up(&(agp_fe.agp_mutex));
return ret_val; return ret_val;
} }
...@@ -1060,7 +1085,7 @@ static struct miscdevice agp_miscdev = ...@@ -1060,7 +1085,7 @@ static struct miscdevice agp_miscdev =
int agp_frontend_initialize(void) int agp_frontend_initialize(void)
{ {
memset(&agp_fe, 0, sizeof(struct agp_front_data)); memset(&agp_fe, 0, sizeof(struct agp_front_data));
AGP_LOCK_INIT(); sema_init(&(agp_fe.agp_mutex), 1);
if (misc_register(&agp_miscdev)) { if (misc_register(&agp_miscdev)) {
printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR); printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR);
......
...@@ -18,7 +18,7 @@ struct agp_3_0_dev { ...@@ -18,7 +18,7 @@ struct agp_3_0_dev {
struct pci_dev *dev; struct pci_dev *dev;
}; };
static int agp_3_0_dev_list_insert(struct list_head *head, struct list_head *new) static void agp_3_0_dev_list_insert(struct list_head *head, struct list_head *new)
{ {
struct agp_3_0_dev *cur, *n = list_entry(new, struct agp_3_0_dev, list); struct agp_3_0_dev *cur, *n = list_entry(new, struct agp_3_0_dev, list);
struct list_head *pos; struct list_head *pos;
...@@ -29,11 +29,9 @@ static int agp_3_0_dev_list_insert(struct list_head *head, struct list_head *new ...@@ -29,11 +29,9 @@ static int agp_3_0_dev_list_insert(struct list_head *head, struct list_head *new
break; break;
} }
list_add_tail(new, pos); list_add_tail(new, pos);
return 0;
} }
static int agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs) static void agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs)
{ {
struct agp_3_0_dev *cur; struct agp_3_0_dev *cur;
struct pci_dev *dev; struct pci_dev *dev;
...@@ -53,7 +51,6 @@ static int agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs) ...@@ -53,7 +51,6 @@ static int agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs)
pos = pos->next; pos = pos->next;
agp_3_0_dev_list_insert(head, tmp); agp_3_0_dev_list_insert(head, tmp);
} }
return 0;
} }
/* /*
...@@ -62,7 +59,8 @@ static int agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs) ...@@ -62,7 +59,8 @@ static int agp_3_0_dev_list_sort(struct agp_3_0_dev *list, unsigned int ndevs)
* lying behind it...) * lying behind it...)
*/ */
static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigned int ndevs) static int agp_3_0_isochronous_node_enable(struct agp_bridge_data *bridge,
struct agp_3_0_dev *dev_list, unsigned int ndevs)
{ {
/* /*
* Convenience structure to make the calculations clearer * Convenience structure to make the calculations clearer
...@@ -77,7 +75,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne ...@@ -77,7 +75,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne
struct agp_3_0_dev *dev; struct agp_3_0_dev *dev;
}; };
struct pci_dev *td = agp_bridge->dev, *dev; struct pci_dev *td = bridge->dev, *dev;
struct list_head *head = &dev_list->list, *pos; struct list_head *head = &dev_list->list, *pos;
struct agp_3_0_dev *cur; struct agp_3_0_dev *cur;
struct isoch_data *master, target; struct isoch_data *master, target;
...@@ -114,11 +112,10 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne ...@@ -114,11 +112,10 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne
* transfers are enabled and consequently whether maxbw will mean * transfers are enabled and consequently whether maxbw will mean
* anything. * anything.
*/ */
if((ret = agp_3_0_dev_list_sort(dev_list, ndevs)) != 0) agp_3_0_dev_list_sort(dev_list, ndevs);
goto free_and_exit;
pci_read_config_dword(td, agp_bridge->capndx + 0x0c, &tnistat); pci_read_config_dword(td, bridge->capndx + 0x0c, &tnistat);
pci_read_config_dword(td, agp_bridge->capndx + 0x04, &tstatus); pci_read_config_dword(td, bridge->capndx+AGPSTAT, &tstatus);
/* Extract power-on defaults from the target */ /* Extract power-on defaults from the target */
target.maxbw = (tnistat >> 16) & 0xff; target.maxbw = (tnistat >> 16) & 0xff;
...@@ -170,13 +167,13 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne ...@@ -170,13 +167,13 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne
* in the target's NISTAT register, so we need to do this now * in the target's NISTAT register, so we need to do this now
* to get an accurate value for ISOCH_N later. * to get an accurate value for ISOCH_N later.
*/ */
pci_read_config_word(td, agp_bridge->capndx + 0x20, &tnicmd); pci_read_config_word(td, bridge->capndx + 0x20, &tnicmd);
tnicmd &= ~(0x3 << 6); tnicmd &= ~(0x3 << 6);
tnicmd |= target.y << 6; tnicmd |= target.y << 6;
pci_write_config_word(td, agp_bridge->capndx + 0x20, tnicmd); pci_write_config_word(td, bridge->capndx + 0x20, tnicmd);
/* Reread the target's ISOCH_N */ /* Reread the target's ISOCH_N */
pci_read_config_dword(td, agp_bridge->capndx + 0x0c, &tnistat); pci_read_config_dword(td, bridge->capndx + 0x0c, &tnistat);
target.n = (tnistat >> 8) & 0xff; target.n = (tnistat >> 8) & 0xff;
/* Calculate the minimum ISOCH_N needed by each master */ /* Calculate the minimum ISOCH_N needed by each master */
...@@ -260,7 +257,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne ...@@ -260,7 +257,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne
? (rem_async + rem_isoch) : step; ? (rem_async + rem_isoch) : step;
pci_read_config_word(dev, cur->capndx + 0x20, &mnicmd); pci_read_config_word(dev, cur->capndx + 0x20, &mnicmd);
pci_read_config_dword(dev, cur->capndx + 0x08, &mcmd); pci_read_config_dword(dev, cur->capndx+AGPCMD, &mcmd);
mnicmd &= ~(0xff << 8); mnicmd &= ~(0xff << 8);
mnicmd &= ~(0x3 << 6); mnicmd &= ~(0x3 << 6);
...@@ -270,7 +267,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne ...@@ -270,7 +267,7 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne
mnicmd |= master[cdev].y << 6; mnicmd |= master[cdev].y << 6;
mcmd |= master[cdev].rq << 24; mcmd |= master[cdev].rq << 24;
pci_write_config_dword(dev, cur->capndx + 0x08, mcmd); pci_write_config_dword(dev, cur->capndx+AGPCMD, mcmd);
pci_write_config_word(dev, cur->capndx + 0x20, mnicmd); pci_write_config_word(dev, cur->capndx + 0x20, mnicmd);
} }
...@@ -288,7 +285,8 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne ...@@ -288,7 +285,8 @@ static int agp_3_0_isochronous_node_enable(struct agp_3_0_dev *dev_list, unsigne
* target by ndevs. Distribute this many slots to each AGP 3.0 device, * target by ndevs. Distribute this many slots to each AGP 3.0 device,
* giving any left over slots to the last device in dev_list. * giving any left over slots to the last device in dev_list.
*/ */
static int agp_3_0_nonisochronous_node_enable(struct agp_3_0_dev *dev_list, unsigned int ndevs) static void agp_3_0_nonisochronous_node_enable(struct agp_bridge_data *bridge,
struct agp_3_0_dev *dev_list, unsigned int ndevs)
{ {
struct agp_3_0_dev *cur; struct agp_3_0_dev *cur;
struct list_head *head = &dev_list->list, *pos; struct list_head *head = &dev_list->list, *pos;
...@@ -296,7 +294,7 @@ static int agp_3_0_nonisochronous_node_enable(struct agp_3_0_dev *dev_list, unsi ...@@ -296,7 +294,7 @@ static int agp_3_0_nonisochronous_node_enable(struct agp_3_0_dev *dev_list, unsi
u32 trq, mrq, rem; u32 trq, mrq, rem;
unsigned int cdev = 0; unsigned int cdev = 0;
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x04, &tstatus); pci_read_config_dword(bridge->dev, bridge->capndx + 0x04, &tstatus);
trq = (tstatus >> 24) & 0xff; trq = (tstatus >> 24) & 0xff;
mrq = trq / ndevs; mrq = trq / ndevs;
...@@ -306,22 +304,20 @@ static int agp_3_0_nonisochronous_node_enable(struct agp_3_0_dev *dev_list, unsi ...@@ -306,22 +304,20 @@ static int agp_3_0_nonisochronous_node_enable(struct agp_3_0_dev *dev_list, unsi
for(pos = head->next; cdev < ndevs; cdev++, pos = pos->next) { for(pos = head->next; cdev < ndevs; cdev++, pos = pos->next) {
cur = list_entry(pos, struct agp_3_0_dev, list); cur = list_entry(pos, struct agp_3_0_dev, list);
pci_read_config_dword(cur->dev, cur->capndx + 0x08, &mcmd); pci_read_config_dword(cur->dev, cur->capndx+AGPCMD, &mcmd);
mcmd &= ~(0xff << 24); mcmd &= ~(0xff << 24);
mcmd |= ((cdev == ndevs - 1) ? rem : mrq) << 24; mcmd |= ((cdev == ndevs - 1) ? rem : mrq) << 24;
pci_write_config_dword(cur->dev, cur->capndx + 0x08, mcmd); pci_write_config_dword(cur->dev, cur->capndx+AGPCMD, mcmd);
} }
return 0;
} }
/* /*
* Fully configure and enable an AGP 3.0 host bridge and all the devices * Fully configure and enable an AGP 3.0 host bridge and all the devices
* lying behind it. * lying behind it.
*/ */
int agp_3_0_node_enable(u32 mode, u32 minor) int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor)
{ {
struct pci_dev *td = agp_bridge->dev, *dev; struct pci_dev *td = bridge->dev, *dev;
u8 mcapndx; u8 mcapndx;
u32 isoch, arqsz, cal_cycle, tmp, rate; u32 isoch, arqsz, cal_cycle, tmp, rate;
u32 tstatus, tcmd, mcmd, mstatus, ncapid; u32 tstatus, tcmd, mcmd, mstatus, ncapid;
...@@ -345,12 +341,22 @@ int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -345,12 +341,22 @@ int agp_3_0_node_enable(u32 mode, u32 minor)
/* Find all AGP devices, and add them to dev_list. */ /* Find all AGP devices, and add them to dev_list. */
pci_for_each_dev(dev) { pci_for_each_dev(dev) {
mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
switch ((dev->class >>8) & 0xff00) { switch ((dev->class >>8) & 0xff00) {
case 0x0600: /* Bridge */
/* Skip bridges. We should call this function for each one. */
continue;
case 0x0001: /* Unclassified device */ case 0x0001: /* Unclassified device */
/* Don't know what this is, but log it for investigation. */
if (mcapndx != 0) {
printk (KERN_INFO PFX "Wacky, found unclassified AGP device. %x:%x\n",
dev->vendor, dev->device);
}
continue;
case 0x0300: /* Display controller */ case 0x0300: /* Display controller */
case 0x0400: /* Multimedia controller */ case 0x0400: /* Multimedia controller */
case 0x0600: /* Bridge */
mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (mcapndx == 0) if (mcapndx == 0)
continue; continue;
...@@ -371,7 +377,7 @@ int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -371,7 +377,7 @@ int agp_3_0_node_enable(u32 mode, u32 minor)
} }
/* Extract some power-on defaults from the target */ /* Extract some power-on defaults from the target */
pci_read_config_dword(td, agp_bridge->capndx + 0x04, &tstatus); pci_read_config_dword(td, bridge->capndx + 0x04, &tstatus);
isoch = (tstatus >> 17) & 0x1; isoch = (tstatus >> 17) & 0x1;
arqsz = (tstatus >> 13) & 0x7; arqsz = (tstatus >> 13) & 0x7;
cal_cycle = (tstatus >> 10) & 0x7; cal_cycle = (tstatus >> 10) & 0x7;
...@@ -409,8 +415,8 @@ int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -409,8 +415,8 @@ int agp_3_0_node_enable(u32 mode, u32 minor)
goto free_and_exit; goto free_and_exit;
} }
mmajor = (ncapid >> 20) & 0xf; mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
mminor = (ncapid >> 16) & 0xf; mminor = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf;
if(mmajor < 3) { if(mmajor < 3) {
printk(KERN_ERR PFX "woah! AGP 2.0 device " printk(KERN_ERR PFX "woah! AGP 2.0 device "
...@@ -463,13 +469,15 @@ int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -463,13 +469,15 @@ int agp_3_0_node_enable(u32 mode, u32 minor)
* masters. This process is dramatically different depending on * masters. This process is dramatically different depending on
* whether isochronous transfers are supported. * whether isochronous transfers are supported.
*/ */
if(isoch != 0) { if (isoch) {
if((ret = agp_3_0_isochronous_node_enable(dev_list, ndevs)) != 0) ret = agp_3_0_isochronous_node_enable(bridge, dev_list, ndevs);
goto free_and_exit; if (ret) {
} else { printk(KERN_INFO PFX "Something bad happened setting "
if((ret = agp_3_0_nonisochronous_node_enable(dev_list,ndevs)) != 0) "up isochronous xfers. Falling back to "
goto free_and_exit; "non-isochronous xfer mode.\n");
}
} }
agp_3_0_nonisochronous_node_enable(bridge, dev_list, ndevs);
/* /*
* Set the calculated minimum supported cal_cycle and minimum * Set the calculated minimum supported cal_cycle and minimum
...@@ -477,7 +485,7 @@ int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -477,7 +485,7 @@ int agp_3_0_node_enable(u32 mode, u32 minor)
* Also set the AGP_ENABLE bit, effectively 'turning on' the * Also set the AGP_ENABLE bit, effectively 'turning on' the
* target (this has to be done _before_ turning on the masters). * target (this has to be done _before_ turning on the masters).
*/ */
pci_read_config_dword(td, agp_bridge->capndx + 0x08, &tcmd); pci_read_config_dword(td, bridge->capndx+AGPCMD, &tcmd);
tcmd &= ~(0x7 << 10); tcmd &= ~(0x7 << 10);
tcmd &= ~0x7; tcmd &= ~0x7;
...@@ -486,7 +494,7 @@ int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -486,7 +494,7 @@ int agp_3_0_node_enable(u32 mode, u32 minor)
tcmd |= 0x1 << 8; tcmd |= 0x1 << 8;
tcmd |= rate; tcmd |= rate;
pci_write_config_dword(td, agp_bridge->capndx + 0x08, tcmd); pci_write_config_dword(td, bridge->capndx+AGPCMD, tcmd);
/* /*
* Set the target's advertised arqsz value, the minimum supported * Set the target's advertised arqsz value, the minimum supported
...@@ -499,16 +507,16 @@ int agp_3_0_node_enable(u32 mode, u32 minor) ...@@ -499,16 +507,16 @@ int agp_3_0_node_enable(u32 mode, u32 minor)
mcapndx = cur->capndx; mcapndx = cur->capndx;
pci_read_config_dword(dev, cur->capndx + 0x08, &mcmd); pci_read_config_dword(dev, cur->capndx+AGPCMD, &mcmd);
mcmd &= ~(0x7 << 13); mcmd &= ~(0x7 << AGPSTAT_ARQSZ_SHIFT);
mcmd &= ~0x7; mcmd &= ~0x7;
mcmd |= arqsz << 13; mcmd |= arqsz << 13;
mcmd |= 0x1 << 8; mcmd |= AGPSTAT_AGP_ENABLE;
mcmd |= rate; mcmd |= rate;
pci_write_config_dword(dev, cur->capndx + 0x08, mcmd); pci_write_config_dword(dev, cur->capndx+AGPCMD, mcmd);
} }
free_and_exit: free_and_exit:
......
/* /*
* AGPGART driver. * AGPGART driver.
* Copyright (C) 2002 Dave Jones. * Copyright (C) 2002-2003 Dave Jones.
* Copyright (C) 1999 Jeff Hartmann. * Copyright (C) 1999 Jeff Hartmann.
* Copyright (C) 1999 Precision Insight, Inc. * Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc. * Copyright (C) 1999 Xi Graphics, Inc.
...@@ -42,19 +42,19 @@ int agp_memory_reserved; ...@@ -42,19 +42,19 @@ int agp_memory_reserved;
/* /*
* Generic routines for handling agp_memory structures - * Generic routines for handling agp_memory structures -
* They use the basic page allocation routines to do the * They use the basic page allocation routines to do the brunt of the work.
* brunt of the work.
*/ */
void agp_free_key(int key) void agp_free_key(int key)
{ {
if (key < 0) if (key < 0)
return; return;
if (key < MAXKEY) if (key < MAXKEY)
clear_bit(key, agp_bridge->key_list); clear_bit(key, agp_bridge->key_list);
} }
EXPORT_SYMBOL(agp_free_key);
static int agp_get_key(void) static int agp_get_key(void)
{ {
...@@ -68,6 +68,7 @@ static int agp_get_key(void) ...@@ -68,6 +68,7 @@ static int agp_get_key(void)
return -1; return -1;
} }
agp_memory *agp_create_memory(int scratch_pages) agp_memory *agp_create_memory(int scratch_pages)
{ {
agp_memory *new; agp_memory *new;
...@@ -94,7 +95,16 @@ agp_memory *agp_create_memory(int scratch_pages) ...@@ -94,7 +95,16 @@ agp_memory *agp_create_memory(int scratch_pages)
new->num_scratch_pages = scratch_pages; new->num_scratch_pages = scratch_pages;
return new; return new;
} }
EXPORT_SYMBOL(agp_create_memory);
/**
* agp_free_memory - free memory associated with an agp_memory pointer.
*
* @curr: agp_memory pointer to be freed.
*
* It is the only function that can be called when the backend is not owned
* by the caller. (So it can free memory on client death.)
*/
void agp_free_memory(agp_memory * curr) void agp_free_memory(agp_memory * curr)
{ {
size_t i; size_t i;
...@@ -106,21 +116,33 @@ void agp_free_memory(agp_memory * curr) ...@@ -106,21 +116,33 @@ void agp_free_memory(agp_memory * curr)
agp_unbind_memory(curr); agp_unbind_memory(curr);
if (curr->type != 0) { if (curr->type != 0) {
agp_bridge->free_by_type(curr); agp_bridge->driver->free_by_type(curr);
return; return;
} }
if (curr->page_count != 0) { if (curr->page_count != 0) {
for (i = 0; i < curr->page_count; i++) { for (i = 0; i < curr->page_count; i++) {
agp_bridge->agp_destroy_page(phys_to_virt(curr->memory[i])); agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i]));
} }
} }
agp_free_key(curr->key); agp_free_key(curr->key);
vfree(curr->memory); vfree(curr->memory);
kfree(curr); kfree(curr);
} }
EXPORT_SYMBOL(agp_free_memory);
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long)) #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
/**
* agp_allocate_memory - allocate a group of pages of a certain type.
*
* @page_count: size_t argument of the number of pages
* @type: u32 argument of the type of memory to be allocated.
*
* Every agp bridge device will allow you to allocate AGP_NORMAL_MEMORY which
* maps to physical ram. Any other type is device dependent.
*
* It returns NULL whenever memory is unavailable.
*/
agp_memory *agp_allocate_memory(size_t page_count, u32 type) agp_memory *agp_allocate_memory(size_t page_count, u32 type)
{ {
int scratch_pages; int scratch_pages;
...@@ -134,7 +156,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type) ...@@ -134,7 +156,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return NULL; return NULL;
if (type != 0) { if (type != 0) {
new = agp_bridge->alloc_by_type(page_count, type); new = agp_bridge->driver->alloc_by_type(page_count, type);
return new; return new;
} }
...@@ -146,7 +168,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type) ...@@ -146,7 +168,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return NULL; return NULL;
for (i = 0; i < page_count; i++) { for (i = 0; i < page_count; i++) {
void *addr = agp_bridge->agp_alloc_page(); void *addr = agp_bridge->driver->agp_alloc_page();
if (addr == NULL) { if (addr == NULL) {
agp_free_memory(new); agp_free_memory(new);
...@@ -160,9 +182,12 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type) ...@@ -160,9 +182,12 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return new; return new;
} }
EXPORT_SYMBOL(agp_allocate_memory);
/* End - Generic routines for handling agp_memory structures */ /* End - Generic routines for handling agp_memory structures */
static int agp_return_size(void) static int agp_return_size(void)
{ {
int current_size; int current_size;
...@@ -170,7 +195,7 @@ static int agp_return_size(void) ...@@ -170,7 +195,7 @@ static int agp_return_size(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
current_size = A_SIZE_8(temp)->size; current_size = A_SIZE_8(temp)->size;
break; break;
...@@ -197,6 +222,7 @@ static int agp_return_size(void) ...@@ -197,6 +222,7 @@ static int agp_return_size(void)
return current_size; return current_size;
} }
int agp_num_entries(void) int agp_num_entries(void)
{ {
int num_entries; int num_entries;
...@@ -204,7 +230,7 @@ int agp_num_entries(void) ...@@ -204,7 +230,7 @@ int agp_num_entries(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
num_entries = A_SIZE_8(temp)->num_entries; num_entries = A_SIZE_8(temp)->num_entries;
break; break;
...@@ -230,9 +256,17 @@ int agp_num_entries(void) ...@@ -230,9 +256,17 @@ int agp_num_entries(void)
num_entries = 0; num_entries = 0;
return num_entries; return num_entries;
} }
EXPORT_SYMBOL_GPL(agp_num_entries);
/* Routine to copy over information structure */
/**
* agp_copy_info - copy bridge state information
*
* @info: agp_kern_info pointer. The caller should insure that this pointer is valid.
*
* This function copies information about the agp bridge device and the state of
* the agp backend into an agp_kern_info pointer.
*/
int agp_copy_info(agp_kern_info * info) int agp_copy_info(agp_kern_info * info)
{ {
memset(info, 0, sizeof(agp_kern_info)); memset(info, 0, sizeof(agp_kern_info));
...@@ -249,20 +283,32 @@ int agp_copy_info(agp_kern_info * info) ...@@ -249,20 +283,32 @@ int agp_copy_info(agp_kern_info * info)
info->aper_size = agp_return_size(); info->aper_size = agp_return_size();
info->max_memory = agp_bridge->max_memory_agp; info->max_memory = agp_bridge->max_memory_agp;
info->current_memory = atomic_read(&agp_bridge->current_memory_agp); info->current_memory = atomic_read(&agp_bridge->current_memory_agp);
info->cant_use_aperture = agp_bridge->cant_use_aperture; info->cant_use_aperture = agp_bridge->driver->cant_use_aperture;
info->vm_ops = agp_bridge->vm_ops; info->vm_ops = agp_bridge->vm_ops;
info->page_mask = ~0UL; info->page_mask = ~0UL;
return 0; return 0;
} }
EXPORT_SYMBOL(agp_copy_info);
/* End - Routine to copy over information structure */ /* End - Routine to copy over information structure */
/* /*
* Routines for handling swapping of agp_memory into the GATT - * Routines for handling swapping of agp_memory into the GATT -
* These routines take agp_memory and insert them into the GATT. * These routines take agp_memory and insert them into the GATT.
* They call device specific routines to actually write to the GATT. * They call device specific routines to actually write to the GATT.
*/ */
/**
* agp_bind_memory - Bind an agp_memory structure into the GATT.
*
* @curr: agp_memory pointer
* @pg_start: an offset into the graphics aperture translation table
*
* It returns -EINVAL if the pointer == NULL.
* It returns -EBUSY if the area of the table requested is already in use.
*/
int agp_bind_memory(agp_memory * curr, off_t pg_start) int agp_bind_memory(agp_memory * curr, off_t pg_start)
{ {
int ret_val; int ret_val;
...@@ -272,10 +318,10 @@ int agp_bind_memory(agp_memory * curr, off_t pg_start) ...@@ -272,10 +318,10 @@ int agp_bind_memory(agp_memory * curr, off_t pg_start)
return -EINVAL; return -EINVAL;
} }
if (curr->is_flushed == FALSE) { if (curr->is_flushed == FALSE) {
CACHE_FLUSH(); agp_bridge->driver->cache_flush();
curr->is_flushed = TRUE; curr->is_flushed = TRUE;
} }
ret_val = agp_bridge->insert_memory(curr, pg_start, curr->type); ret_val = agp_bridge->driver->insert_memory(curr, pg_start, curr->type);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
...@@ -284,7 +330,17 @@ int agp_bind_memory(agp_memory * curr, off_t pg_start) ...@@ -284,7 +330,17 @@ int agp_bind_memory(agp_memory * curr, off_t pg_start)
curr->pg_start = pg_start; curr->pg_start = pg_start;
return 0; return 0;
} }
EXPORT_SYMBOL(agp_bind_memory);
/**
* agp_unbind_memory - Removes an agp_memory structure from the GATT
*
* @curr: agp_memory pointer to be removed from the GATT.
*
* It returns -EINVAL if this piece of agp_memory is not currently bound to
* the graphics aperture translation table or if the agp_memory pointer == NULL
*/
int agp_unbind_memory(agp_memory * curr) int agp_unbind_memory(agp_memory * curr)
{ {
int ret_val; int ret_val;
...@@ -295,7 +351,7 @@ int agp_unbind_memory(agp_memory * curr) ...@@ -295,7 +351,7 @@ int agp_unbind_memory(agp_memory * curr)
if (curr->is_bound != TRUE) if (curr->is_bound != TRUE)
return -EINVAL; return -EINVAL;
ret_val = agp_bridge->remove_memory(curr, curr->pg_start, curr->type); ret_val = agp_bridge->driver->remove_memory(curr, curr->pg_start, curr->type);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
...@@ -304,6 +360,7 @@ int agp_unbind_memory(agp_memory * curr) ...@@ -304,6 +360,7 @@ int agp_unbind_memory(agp_memory * curr)
curr->pg_start = 0; curr->pg_start = 0;
return 0; return 0;
} }
EXPORT_SYMBOL(agp_unbind_memory);
/* End - Routines for handling swapping of agp_memory into the GATT */ /* End - Routines for handling swapping of agp_memory into the GATT */
...@@ -328,50 +385,44 @@ u32 agp_collect_device_status(u32 mode, u32 command) ...@@ -328,50 +385,44 @@ u32 agp_collect_device_status(u32 mode, u32 command)
pci_read_config_dword(device, agp + PCI_AGP_STATUS, &scratch); pci_read_config_dword(device, agp + PCI_AGP_STATUS, &scratch);
/* adjust RQ depth */ /* adjust RQ depth */
command = ((command & ~0xff000000) | command = ((command & ~AGPSTAT_RQ_DEPTH) |
min_t(u32, (mode & 0xff000000), min_t(u32, (mode & AGPSTAT_RQ_DEPTH),
min_t(u32, (command & 0xff000000), min_t(u32, (command & AGPSTAT_RQ_DEPTH),
(scratch & 0xff000000)))); (scratch & AGPSTAT_RQ_DEPTH))));
/* disable SBA if it's not supported */ /* disable SBA if it's not supported */
if (!((command & 0x00000200) && if (!((command & AGPSTAT_SBA) && (scratch & AGPSTAT_SBA) && (mode & AGPSTAT_SBA)))
(scratch & 0x00000200) && command &= ~AGPSTAT_SBA;
(mode & 0x00000200)))
command &= ~0x00000200;
/* disable FW if it's not supported */ /* disable FW if it's not supported */
if (!((command & 0x00000010) && if (!((command & AGPSTAT_FW) && (scratch & AGPSTAT_FW) && (mode & AGPSTAT_FW)))
(scratch & 0x00000010) && command &= ~AGPSTAT_FW;
(mode & 0x00000010)))
command &= ~0x00000010; /* Set speed */
if (!((command & AGPSTAT2_4X) && (scratch & AGPSTAT2_4X) && (mode & AGPSTAT2_4X)))
if (!((command & 4) && command &= ~AGPSTAT2_4X;
(scratch & 4) &&
(mode & 4))) if (!((command & AGPSTAT2_2X) && (scratch & AGPSTAT2_2X) && (mode & AGPSTAT2_2X)))
command &= ~0x00000004; command &= ~AGPSTAT2_2X;
if (!((command & 2) && if (!((command & AGPSTAT2_1X) && (scratch & AGPSTAT2_1X) && (mode & AGPSTAT2_1X)))
(scratch & 2) && command &= ~AGPSTAT2_1X;
(mode & 2)))
command &= ~0x00000002;
if (!((command & 1) &&
(scratch & 1) &&
(mode & 1)))
command &= ~0x00000001;
} }
if (command & 4) /* Now we know what mode it should be, clear out the unwanted bits. */
command &= ~3; /* 4X */ if (command & AGPSTAT2_4X)
command &= ~(AGPSTAT2_1X | AGPSTAT2_2X); /* 4X */
if (command & 2) if (command & AGPSTAT2_2X)
command &= ~5; /* 2X (8X for AGP3.0) */ command &= ~(AGPSTAT2_1X | AGPSTAT2_4X); /* 2X */
if (command & 1) if (command & AGPSTAT2_1X)
command &= ~6; /* 1X (4X for AGP3.0) */ command &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1Xf */
return command; return command;
} }
EXPORT_SYMBOL(agp_collect_device_status);
void agp_device_command(u32 command, int agp_v3) void agp_device_command(u32 command, int agp_v3)
{ {
...@@ -392,6 +443,8 @@ void agp_device_command(u32 command, int agp_v3) ...@@ -392,6 +443,8 @@ void agp_device_command(u32 command, int agp_v3)
pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command); pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command);
} }
} }
EXPORT_SYMBOL(agp_device_command);
void agp_generic_enable(u32 mode) void agp_generic_enable(u32 mode)
{ {
...@@ -408,7 +461,7 @@ void agp_generic_enable(u32 mode) ...@@ -408,7 +461,7 @@ void agp_generic_enable(u32 mode)
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x4, &agp_3_0); pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x4, &agp_3_0);
/* Check to see if we are operating in 3.0 mode */ /* Check to see if we are operating in 3.0 mode */
if((agp_3_0 >> 3) & 0x1) { if((agp_3_0 >> 3) & 0x1) {
agp_3_0_node_enable(mode, minor); agp_3_0_node_enable(agp_bridge, mode, minor);
return; return;
} else { } else {
printk (KERN_INFO PFX "not in AGP 3.0 mode, falling back to 2.x\n"); printk (KERN_INFO PFX "not in AGP 3.0 mode, falling back to 2.x\n");
...@@ -420,12 +473,14 @@ void agp_generic_enable(u32 mode) ...@@ -420,12 +473,14 @@ void agp_generic_enable(u32 mode)
agp_bridge->capndx + PCI_AGP_STATUS, &command); agp_bridge->capndx + PCI_AGP_STATUS, &command);
command = agp_collect_device_status(mode, command); command = agp_collect_device_status(mode, command);
command |= 0x100; command |= AGPSTAT_AGP_ENABLE;
pci_write_config_dword(agp_bridge->dev, pci_write_config_dword(agp_bridge->dev,
agp_bridge->capndx + PCI_AGP_COMMAND, command); agp_bridge->capndx + PCI_AGP_COMMAND, command);
agp_device_command(command, 0); agp_device_command(command, 0);
} }
EXPORT_SYMBOL(agp_generic_enable);
int agp_generic_create_gatt_table(void) int agp_generic_create_gatt_table(void)
{ {
...@@ -439,7 +494,7 @@ int agp_generic_create_gatt_table(void) ...@@ -439,7 +494,7 @@ int agp_generic_create_gatt_table(void)
struct page *page; struct page *page;
/* The generic routines can't handle 2 level gatt's */ /* The generic routines can't handle 2 level gatt's */
if (agp_bridge->size_type == LVL2_APER_SIZE) if (agp_bridge->driver->size_type == LVL2_APER_SIZE)
return -EINVAL; return -EINVAL;
table = NULL; table = NULL;
...@@ -447,9 +502,9 @@ int agp_generic_create_gatt_table(void) ...@@ -447,9 +502,9 @@ int agp_generic_create_gatt_table(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
size = page_order = num_entries = 0; size = page_order = num_entries = 0;
if (agp_bridge->size_type != FIXED_APER_SIZE) { if (agp_bridge->driver->size_type != FIXED_APER_SIZE) {
do { do {
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
size = A_SIZE_8(temp)->size; size = A_SIZE_8(temp)->size;
page_order = page_order =
...@@ -480,19 +535,17 @@ int agp_generic_create_gatt_table(void) ...@@ -480,19 +535,17 @@ int agp_generic_create_gatt_table(void)
if (table == NULL) { if (table == NULL) {
i++; i++;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
agp_bridge->current_size = A_IDX8(); agp_bridge->current_size = A_IDX8(agp_bridge);
break; break;
case U16_APER_SIZE: case U16_APER_SIZE:
agp_bridge->current_size = A_IDX16(); agp_bridge->current_size = A_IDX16(agp_bridge);
break; break;
case U32_APER_SIZE: case U32_APER_SIZE:
agp_bridge->current_size = A_IDX32(); agp_bridge->current_size = A_IDX32(agp_bridge);
break; break;
/* This case will never really /* This case will never really happen. */
* happen.
*/
case FIXED_APER_SIZE: case FIXED_APER_SIZE:
case LVL2_APER_SIZE: case LVL2_APER_SIZE:
default: default:
...@@ -504,7 +557,7 @@ int agp_generic_create_gatt_table(void) ...@@ -504,7 +557,7 @@ int agp_generic_create_gatt_table(void)
} else { } else {
agp_bridge->aperture_size_idx = i; agp_bridge->aperture_size_idx = i;
} }
} while ((table == NULL) && (i < agp_bridge->num_aperture_sizes)); } while (!table && (i < agp_bridge->driver->num_aperture_sizes));
} else { } else {
size = ((struct aper_size_info_fixed *) temp)->size; size = ((struct aper_size_info_fixed *) temp)->size;
page_order = ((struct aper_size_info_fixed *) temp)->page_order; page_order = ((struct aper_size_info_fixed *) temp)->page_order;
...@@ -522,10 +575,11 @@ int agp_generic_create_gatt_table(void) ...@@ -522,10 +575,11 @@ int agp_generic_create_gatt_table(void)
agp_bridge->gatt_table_real = (u32 *) table; agp_bridge->gatt_table_real = (u32 *) table;
agp_gatt_table = (void *)table; agp_gatt_table = (void *)table;
CACHE_FLUSH();
agp_bridge->driver->cache_flush();
agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table), agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
(PAGE_SIZE * (1 << page_order))); (PAGE_SIZE * (1 << page_order)));
CACHE_FLUSH(); agp_bridge->driver->cache_flush();
if (agp_bridge->gatt_table == NULL) { if (agp_bridge->gatt_table == NULL) {
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
...@@ -543,16 +597,21 @@ int agp_generic_create_gatt_table(void) ...@@ -543,16 +597,21 @@ int agp_generic_create_gatt_table(void)
return 0; return 0;
} }
EXPORT_SYMBOL(agp_generic_create_gatt_table);
int agp_generic_suspend(void) int agp_generic_suspend(void)
{ {
return 0; return 0;
} }
EXPORT_SYMBOL(agp_generic_suspend);
void agp_generic_resume(void) void agp_generic_resume(void)
{ {
return; return;
} }
EXPORT_SYMBOL(agp_generic_resume);
int agp_generic_free_gatt_table(void) int agp_generic_free_gatt_table(void)
{ {
...@@ -563,7 +622,7 @@ int agp_generic_free_gatt_table(void) ...@@ -563,7 +622,7 @@ int agp_generic_free_gatt_table(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
page_order = A_SIZE_8(temp)->page_order; page_order = A_SIZE_8(temp)->page_order;
break; break;
...@@ -587,8 +646,7 @@ int agp_generic_free_gatt_table(void) ...@@ -587,8 +646,7 @@ int agp_generic_free_gatt_table(void)
/* Do not worry about freeing memory, because if this is /* Do not worry about freeing memory, because if this is
* called, then all agp memory is deallocated and removed * called, then all agp memory is deallocated and removed
* from the table. * from the table. */
*/
iounmap(agp_bridge->gatt_table); iounmap(agp_bridge->gatt_table);
table = (char *) agp_bridge->gatt_table_real; table = (char *) agp_bridge->gatt_table_real;
...@@ -598,8 +656,16 @@ int agp_generic_free_gatt_table(void) ...@@ -598,8 +656,16 @@ int agp_generic_free_gatt_table(void)
ClearPageReserved(page); ClearPageReserved(page);
free_pages((unsigned long) agp_bridge->gatt_table_real, page_order); free_pages((unsigned long) agp_bridge->gatt_table_real, page_order);
agp_gatt_table = NULL;
agp_bridge->gatt_table = NULL;
agp_bridge->gatt_table_real = NULL;
agp_bridge->gatt_bus_addr = 0;
return 0; return 0;
} }
EXPORT_SYMBOL(agp_generic_free_gatt_table);
int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type) int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
{ {
...@@ -610,7 +676,7 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -610,7 +676,7 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
num_entries = A_SIZE_8(temp)->num_entries; num_entries = A_SIZE_8(temp)->num_entries;
break; break;
...@@ -647,24 +713,27 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -647,24 +713,27 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
j = pg_start; j = pg_start;
while (j < (pg_start + mem->page_count)) { while (j < (pg_start + mem->page_count)) {
if (!PGE_EMPTY(agp_bridge->gatt_table[j])) { if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[j])) {
return -EBUSY; return -EBUSY;
} }
j++; j++;
} }
if (mem->is_flushed == FALSE) { if (mem->is_flushed == FALSE) {
CACHE_FLUSH(); agp_bridge->driver->cache_flush();
mem->is_flushed = TRUE; mem->is_flushed = TRUE;
} }
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
agp_bridge->gatt_table[j] = agp_bridge->gatt_table[j] =
agp_bridge->mask_memory(mem->memory[i], mem->type); agp_bridge->driver->mask_memory(
mem->memory[i], mem->type);
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
EXPORT_SYMBOL(agp_generic_insert_memory);
int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type) int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
{ {
...@@ -681,14 +750,18 @@ int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -681,14 +750,18 @@ int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
(unsigned long) agp_bridge->scratch_page; (unsigned long) agp_bridge->scratch_page;
} }
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
EXPORT_SYMBOL(agp_generic_remove_memory);
agp_memory *agp_generic_alloc_by_type(size_t page_count, int type) agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
{ {
return NULL; return NULL;
} }
EXPORT_SYMBOL(agp_generic_alloc_by_type);
void agp_generic_free_by_type(agp_memory * curr) void agp_generic_free_by_type(agp_memory * curr)
{ {
...@@ -698,13 +771,13 @@ void agp_generic_free_by_type(agp_memory * curr) ...@@ -698,13 +771,13 @@ void agp_generic_free_by_type(agp_memory * curr)
agp_free_key(curr->key); agp_free_key(curr->key);
kfree(curr); kfree(curr);
} }
EXPORT_SYMBOL(agp_generic_free_by_type);
/* /*
* Basic Page Allocation Routines - * Basic Page Allocation Routines -
* These routines handle page allocation * These routines handle page allocation and by default they reserve the allocated
* and by default they reserve the allocated * memory. They also handle incrementing the current_memory_agp value, Which is checked
* memory. They also handle incrementing the
* current_memory_agp value, Which is checked
* against a maximum value. * against a maximum value.
*/ */
...@@ -723,6 +796,8 @@ void *agp_generic_alloc_page(void) ...@@ -723,6 +796,8 @@ void *agp_generic_alloc_page(void)
atomic_inc(&agp_bridge->current_memory_agp); atomic_inc(&agp_bridge->current_memory_agp);
return page_address(page); return page_address(page);
} }
EXPORT_SYMBOL(agp_generic_alloc_page);
void agp_generic_destroy_page(void *addr) void agp_generic_destroy_page(void *addr)
{ {
...@@ -738,41 +813,39 @@ void agp_generic_destroy_page(void *addr) ...@@ -738,41 +813,39 @@ void agp_generic_destroy_page(void *addr)
free_page((unsigned long)addr); free_page((unsigned long)addr);
atomic_dec(&agp_bridge->current_memory_agp); atomic_dec(&agp_bridge->current_memory_agp);
} }
EXPORT_SYMBOL(agp_generic_destroy_page);
/* End Basic Page Allocation Routines */ /* End Basic Page Allocation Routines */
/**
* agp_enable - initialise the agp point-to-point connection.
*
* @mode: agp mode register value to configure with.
*/
void agp_enable(u32 mode) void agp_enable(u32 mode)
{ {
if (agp_bridge->type == NOT_SUPPORTED) if (agp_bridge->type == NOT_SUPPORTED)
return; return;
agp_bridge->agp_enable(mode); agp_bridge->driver->agp_enable(mode);
} }
EXPORT_SYMBOL(agp_free_memory);
EXPORT_SYMBOL(agp_allocate_memory);
EXPORT_SYMBOL(agp_copy_info);
EXPORT_SYMBOL(agp_create_memory);
EXPORT_SYMBOL(agp_bind_memory);
EXPORT_SYMBOL(agp_unbind_memory);
EXPORT_SYMBOL(agp_free_key);
EXPORT_SYMBOL(agp_enable); EXPORT_SYMBOL(agp_enable);
EXPORT_SYMBOL(agp_bridge);
EXPORT_SYMBOL(agp_generic_alloc_page);
EXPORT_SYMBOL(agp_generic_destroy_page);
EXPORT_SYMBOL(agp_generic_suspend);
EXPORT_SYMBOL(agp_generic_resume);
EXPORT_SYMBOL(agp_generic_enable);
EXPORT_SYMBOL(agp_generic_create_gatt_table);
EXPORT_SYMBOL(agp_generic_free_gatt_table);
EXPORT_SYMBOL(agp_generic_insert_memory);
EXPORT_SYMBOL(agp_generic_remove_memory);
EXPORT_SYMBOL(agp_generic_alloc_by_type);
EXPORT_SYMBOL(agp_generic_free_by_type);
EXPORT_SYMBOL(global_cache_flush);
EXPORT_SYMBOL(agp_device_command); #ifdef CONFIG_SMP
EXPORT_SYMBOL(agp_collect_device_status); static void ipi_handler(void *null)
{
flush_agp_cache();
}
#endif
EXPORT_SYMBOL_GPL(agp_num_entries); void global_cache_flush(void)
{
#ifdef CONFIG_SMP
if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0)
panic(PFX "timed out waiting for the other CPUs!\n");
#else
flush_agp_cache();
#endif
}
EXPORT_SYMBOL(global_cache_flush);
...@@ -285,7 +285,7 @@ static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -285,7 +285,7 @@ static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type)
} }
if (mem->is_flushed == FALSE) { if (mem->is_flushed == FALSE) {
CACHE_FLUSH(); global_cache_flush();
mem->is_flushed = TRUE; mem->is_flushed = TRUE;
} }
...@@ -296,11 +296,11 @@ static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -296,11 +296,11 @@ static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type)
for (k = 0; for (k = 0;
k < hp->io_pages_per_kpage; k < hp->io_pages_per_kpage;
k++, j++, paddr += hp->io_page_size) { k++, j++, paddr += hp->io_page_size) {
hp->gatt[j] = agp_bridge->mask_memory(paddr, type); hp->gatt[j] = agp_bridge->driver->mask_memory(paddr, type);
} }
} }
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
...@@ -319,7 +319,7 @@ static int hp_zx1_remove_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -319,7 +319,7 @@ static int hp_zx1_remove_memory(agp_memory * mem, off_t pg_start, int type)
hp->gatt[i] = agp_bridge->scratch_page; hp->gatt[i] = agp_bridge->scratch_page;
} }
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
...@@ -328,58 +328,62 @@ static unsigned long hp_zx1_mask_memory(unsigned long addr, int type) ...@@ -328,58 +328,62 @@ static unsigned long hp_zx1_mask_memory(unsigned long addr, int type)
return HP_ZX1_PDIR_VALID_BIT | addr; return HP_ZX1_PDIR_VALID_BIT | addr;
} }
static int __init hp_zx1_setup (struct pci_dev *pdev __attribute__((unused))) struct agp_bridge_driver hp_zx1_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = hp_zx1_masks; .masks = hp_zx1_masks,
agp_bridge->dev_private_data = NULL; .size_type = FIXED_APER_SIZE,
agp_bridge->size_type = FIXED_APER_SIZE; .configure = hp_zx1_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = hp_zx1_fetch_size,
agp_bridge->configure = hp_zx1_configure; .cleanup = hp_zx1_cleanup,
agp_bridge->fetch_size = hp_zx1_fetch_size; .tlb_flush = hp_zx1_tlbflush,
agp_bridge->cleanup = hp_zx1_cleanup; .mask_memory = hp_zx1_mask_memory,
agp_bridge->tlb_flush = hp_zx1_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = hp_zx1_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = hp_zx1_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = hp_zx1_free_gatt_table,
agp_bridge->create_gatt_table = hp_zx1_create_gatt_table; .insert_memory = hp_zx1_insert_memory,
agp_bridge->free_gatt_table = hp_zx1_free_gatt_table; .remove_memory = hp_zx1_remove_memory,
agp_bridge->insert_memory = hp_zx1_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = hp_zx1_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .cant_use_aperture = 1,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; };
agp_bridge->cant_use_aperture = 1;
return hp_zx1_ioc_init();
}
static int __init agp_find_supported_device(struct pci_dev *dev) static int __init agp_hp_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{ {
agp_bridge->dev = dev; struct agp_bridge_data *bridge;
int error;
/* ZX1 LBAs can be either PCI or AGP bridges */ /* ZX1 LBAs can be either PCI or AGP bridges */
if (pci_find_capability(dev, PCI_CAP_ID_AGP)) { if (!pci_find_capability(pdev, PCI_CAP_ID_AGP))
printk(KERN_INFO PFX "Detected HP ZX1 AGP chipset at %s\n", return -ENODEV;
dev->slot_name);
agp_bridge->type = HP_ZX1;
agp_bridge->dev = dev;
return hp_zx1_setup(dev);
}
return -ENODEV;
}
static struct agp_driver hp_agp_driver = { printk(KERN_INFO PFX "Detected HP ZX1 AGP chipset at %s\n",
.owner = THIS_MODULE, pdev->slot_name);
};
error = hp_zx1_ioc_init();
if (error)
return error;
static int __init agp_hp_probe (struct pci_dev *dev, const struct pci_device_id *ent) bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &hp_zx1_driver;
bridge->dev = pdev;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_hp_remove(struct pci_dev *pdev)
{ {
if (agp_find_supported_device(dev) == 0) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
hp_agp_driver.dev = dev;
agp_register_driver(&hp_agp_driver); agp_remove_bridge(bridge);
return 0; agp_put_bridge(bridge);
}
return -ENODEV;
} }
static struct pci_device_id agp_hp_pci_table[] __initdata = { static struct pci_device_id agp_hp_pci_table[] __initdata = {
...@@ -400,22 +404,16 @@ static struct __initdata pci_driver agp_hp_pci_driver = { ...@@ -400,22 +404,16 @@ static struct __initdata pci_driver agp_hp_pci_driver = {
.name = "agpgart-hp", .name = "agpgart-hp",
.id_table = agp_hp_pci_table, .id_table = agp_hp_pci_table,
.probe = agp_hp_probe, .probe = agp_hp_probe,
.remove = agp_hp_remove,
}; };
static int __init agp_hp_init(void) static int __init agp_hp_init(void)
{ {
int ret_val; return pci_module_init(&agp_hp_pci_driver);
ret_val = pci_module_init(&agp_hp_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_hp_cleanup(void) static void __exit agp_hp_cleanup(void)
{ {
agp_unregister_driver(&hp_agp_driver);
pci_unregister_driver(&agp_hp_pci_driver); pci_unregister_driver(&agp_hp_pci_driver);
} }
......
...@@ -69,7 +69,7 @@ static struct { ...@@ -69,7 +69,7 @@ static struct {
} *lp_desc; } *lp_desc;
} i460; } i460;
static const struct aper_size_info_8 i460_sizes[3] = static struct aper_size_info_8 i460_sizes[3] =
{ {
/* /*
* The 32GB aperture is only available with a 4M GART page size. Due to the * The 32GB aperture is only available with a 4M GART page size. Due to the
...@@ -107,7 +107,7 @@ static int i460_fetch_size (void) ...@@ -107,7 +107,7 @@ static int i460_fetch_size (void)
return 0; return 0;
} }
values = A_SIZE_8(agp_bridge->aperture_sizes); values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp); pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp);
...@@ -130,7 +130,7 @@ static int i460_fetch_size (void) ...@@ -130,7 +130,7 @@ static int i460_fetch_size (void)
else else
i460.dynamic_apbase = INTEL_I460_APBASE; i460.dynamic_apbase = INTEL_I460_APBASE;
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
/* /*
* Dynamically calculate the proper num_entries and page_order values for * Dynamically calculate the proper num_entries and page_order values for
* the define aperture sizes. Take care not to shift off the end of * the define aperture sizes. Take care not to shift off the end of
...@@ -140,7 +140,7 @@ static int i460_fetch_size (void) ...@@ -140,7 +140,7 @@ static int i460_fetch_size (void)
values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT); values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT);
} }
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
/* Neglect control bits when matching up size_value */ /* Neglect control bits when matching up size_value */
if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) { if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i); agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
...@@ -294,7 +294,7 @@ static int i460_insert_memory_small_io_page (agp_memory *mem, off_t pg_start, in ...@@ -294,7 +294,7 @@ static int i460_insert_memory_small_io_page (agp_memory *mem, off_t pg_start, in
j = io_pg_start; j = io_pg_start;
while (j < (io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count)) { while (j < (io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count)) {
if (!PGE_EMPTY(RD_GATT(j))) { if (!PGE_EMPTY(agp_bridge, RD_GATT(j))) {
pr_debug("i460_insert_memory_small_io_page: GATT[%d]=0x%x is busy\n", pr_debug("i460_insert_memory_small_io_page: GATT[%d]=0x%x is busy\n",
j, RD_GATT(j)); j, RD_GATT(j));
return -EBUSY; return -EBUSY;
...@@ -306,7 +306,7 @@ static int i460_insert_memory_small_io_page (agp_memory *mem, off_t pg_start, in ...@@ -306,7 +306,7 @@ static int i460_insert_memory_small_io_page (agp_memory *mem, off_t pg_start, in
for (i = 0, j = io_pg_start; i < mem->page_count; i++) { for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
paddr = mem->memory[i]; paddr = mem->memory[i];
for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size)
WR_GATT(j, agp_bridge->mask_memory(paddr, mem->type)); WR_GATT(j, agp_bridge->driver->mask_memory(paddr, mem->type));
} }
WR_FLUSH_GATT(j - 1); WR_FLUSH_GATT(j - 1);
return 0; return 0;
...@@ -417,7 +417,7 @@ static int i460_insert_memory_large_io_page (agp_memory * mem, off_t pg_start, i ...@@ -417,7 +417,7 @@ static int i460_insert_memory_large_io_page (agp_memory * mem, off_t pg_start, i
if (i460_alloc_large_page(lp) < 0) if (i460_alloc_large_page(lp) < 0)
return -ENOMEM; return -ENOMEM;
pg = lp - i460.lp_desc; pg = lp - i460.lp_desc;
WR_GATT(pg, agp_bridge->mask_memory(lp->paddr, 0)); WR_GATT(pg, agp_bridge->driver->mask_memory(lp->paddr, 0));
WR_FLUSH_GATT(pg); WR_FLUSH_GATT(pg);
} }
...@@ -439,7 +439,7 @@ static int i460_remove_memory_large_io_page (agp_memory * mem, off_t pg_start, i ...@@ -439,7 +439,7 @@ static int i460_remove_memory_large_io_page (agp_memory * mem, off_t pg_start, i
struct lp_desc *start, *end, *lp; struct lp_desc *start, *end, *lp;
void *temp; void *temp;
temp = agp_bridge->current_size; temp = agp_bridge->driver->current_size;
num_entries = A_SIZE_8(temp)->num_entries; num_entries = A_SIZE_8(temp)->num_entries;
/* Figure out what pg_start means in terms of our large GART pages */ /* Figure out what pg_start means in terms of our large GART pages */
...@@ -519,64 +519,71 @@ static void i460_destroy_page (void *page) ...@@ -519,64 +519,71 @@ static void i460_destroy_page (void *page)
static unsigned long i460_mask_memory (unsigned long addr, int type) static unsigned long i460_mask_memory (unsigned long addr, int type)
{ {
/* Make sure the returned address is a valid GATT entry */ /* Make sure the returned address is a valid GATT entry */
return (agp_bridge->masks[0].mask return (agp_bridge->driver->masks[0].mask
| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12)); | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12));
} }
static int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused))) struct agp_bridge_driver intel_i460_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = i460_masks; .masks = i460_masks,
agp_bridge->aperture_sizes = (void *) i460_sizes; .aperture_sizes = i460_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = U8_APER_SIZE,
agp_bridge->num_aperture_sizes = 3; .num_aperture_sizes = 3,
agp_bridge->dev_private_data = NULL; .configure = i460_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = i460_fetch_size,
agp_bridge->configure = i460_configure; .cleanup = i460_cleanup,
agp_bridge->fetch_size = i460_fetch_size; .tlb_flush = i460_tlb_flush,
agp_bridge->cleanup = i460_cleanup; .mask_memory = i460_mask_memory,
agp_bridge->tlb_flush = i460_tlb_flush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = i460_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = i460_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = i460_free_gatt_table,
agp_bridge->create_gatt_table = i460_create_gatt_table;
agp_bridge->free_gatt_table = i460_free_gatt_table;
#if I460_LARGE_IO_PAGES #if I460_LARGE_IO_PAGES
agp_bridge->insert_memory = i460_insert_memory; .insert_memory = i460_insert_memory,
agp_bridge->remove_memory = i460_remove_memory; .remove_memory = i460_remove_memory,
agp_bridge->agp_alloc_page = i460_alloc_page; .agp_alloc_page = i460_alloc_page,
agp_bridge->agp_destroy_page = i460_destroy_page; .agp_destroy_page = i460_destroy_page,
#else #else
agp_bridge->insert_memory = i460_insert_memory_small_io_page; .insert_memory = i460_insert_memory_small_io_page,
agp_bridge->remove_memory = i460_remove_memory_small_io_page; .remove_memory = i460_remove_memory_small_io_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .agp_destroy_page = agp_generic_destroy_page,
#endif #endif
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->free_by_type = agp_generic_free_by_type; .free_by_type = agp_generic_free_by_type,
agp_bridge->suspend = agp_generic_suspend; .suspend = agp_generic_suspend,
agp_bridge->resume = agp_generic_resume; .resume = agp_generic_resume,
agp_bridge->cant_use_aperture = 1; .cant_use_aperture = 1,
return 0;
}
static struct agp_driver i460_agp_driver = {
.owner = THIS_MODULE,
}; };
static int __init agp_intel_i460_probe (struct pci_dev *dev, const struct pci_device_id *ent) static int __init agp_intel_i460_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{ {
u8 cap_ptr = 0; struct agp_bridge_data *bridge;
u8 cap_ptr;
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (cap_ptr == 0) if (!cap_ptr)
return -ENODEV; return -ENODEV;
agp_bridge->dev = dev; bridge = agp_alloc_bridge();
agp_bridge->capndx = cap_ptr; if (!bridge)
intel_i460_setup(dev); return -ENOMEM;
i460_agp_driver.dev = dev;
agp_register_driver(&i460_agp_driver); bridge->driver = &intel_i460_driver;
return 0; bridge->dev = pdev;
bridge->capndx = cap_ptr;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_intel_i460_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_intel_i460_pci_table[] __initdata = { static struct pci_device_id agp_intel_i460_pci_table[] __initdata = {
...@@ -597,22 +604,16 @@ static struct __initdata pci_driver agp_intel_i460_pci_driver = { ...@@ -597,22 +604,16 @@ static struct __initdata pci_driver agp_intel_i460_pci_driver = {
.name = "agpgart-intel-i460", .name = "agpgart-intel-i460",
.id_table = agp_intel_i460_pci_table, .id_table = agp_intel_i460_pci_table,
.probe = agp_intel_i460_probe, .probe = agp_intel_i460_probe,
.remove = agp_intel_i460_remove,
}; };
static int __init agp_intel_i460_init(void) static int __init agp_intel_i460_init(void)
{ {
int ret_val; return pci_module_init(&agp_intel_i460_pci_driver);
ret_val = pci_module_init(&agp_intel_i460_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_intel_i460_cleanup(void) static void __exit agp_intel_i460_cleanup(void)
{ {
agp_unregister_driver(&i460_agp_driver);
pci_unregister_driver(&agp_intel_i460_pci_driver); pci_unregister_driver(&agp_intel_i460_pci_driver);
} }
......
...@@ -45,7 +45,7 @@ static int intel_i810_fetch_size(void) ...@@ -45,7 +45,7 @@ static int intel_i810_fetch_size(void)
struct aper_size_info_fixed *values; struct aper_size_info_fixed *values;
pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc); pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc);
values = A_SIZE_FIX(agp_bridge->aperture_sizes); values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
printk(KERN_WARNING PFX "i810 is disabled\n"); printk(KERN_WARNING PFX "i810 is disabled\n");
...@@ -89,9 +89,9 @@ static int intel_i810_configure(void) ...@@ -89,9 +89,9 @@ static int intel_i810_configure(void)
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED); agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
CACHE_FLUSH(); global_cache_flush();
if (agp_bridge->needs_scratch_page == TRUE) { if (agp_bridge->driver->needs_scratch_page) {
for (i = 0; i < current_size->num_entries; i++) { for (i = 0; i < current_size->num_entries; i++) {
OUTREG32(intel_i810_private.registers, OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (i * 4), I810_PTE_BASE + (i * 4),
...@@ -130,23 +130,22 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start, ...@@ -130,23 +130,22 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
return -EINVAL; return -EINVAL;
} }
for (j = pg_start; j < (pg_start + mem->page_count); j++) { for (j = pg_start; j < (pg_start + mem->page_count); j++) {
if (!PGE_EMPTY(agp_bridge->gatt_table[j])) { if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[j]))
return -EBUSY; return -EBUSY;
}
} }
if (type != 0 || mem->type != 0) { if (type != 0 || mem->type != 0) {
if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) { if ((type == AGP_DCACHE_MEMORY) && (mem->type == AGP_DCACHE_MEMORY)) {
/* special insert */ /* special insert */
CACHE_FLUSH(); global_cache_flush();
for (i = pg_start; i < (pg_start + mem->page_count); i++) { for (i = pg_start; i < (pg_start + mem->page_count); i++) {
OUTREG32(intel_i810_private.registers, OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (i * 4), I810_PTE_BASE + (i * 4),
(i * 4096) | I810_PTE_LOCAL | (i * 4096) | I810_PTE_LOCAL |
I810_PTE_VALID); I810_PTE_VALID);
} }
CACHE_FLUSH(); global_cache_flush();
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
if((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY)) if((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY))
...@@ -155,15 +154,15 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start, ...@@ -155,15 +154,15 @@ static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
} }
insert: insert:
CACHE_FLUSH(); global_cache_flush();
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
OUTREG32(intel_i810_private.registers, OUTREG32(intel_i810_private.registers,
I810_PTE_BASE + (j * 4), I810_PTE_BASE + (j * 4),
agp_bridge->mask_memory(mem->memory[i], mem->type)); agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
} }
CACHE_FLUSH(); global_cache_flush();
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
...@@ -178,58 +177,61 @@ static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start, ...@@ -178,58 +177,61 @@ static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
agp_bridge->scratch_page); agp_bridge->scratch_page);
} }
CACHE_FLUSH(); global_cache_flush();
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
/*
* The i810/i830 requires a physical address to program its mouse
* pointer into hardware.
* However the Xserver still writes to it through the agp aperture.
*/
static agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
{
agp_memory *new;
void *addr;
if (pg_count != 1)
return NULL;
addr = agp_bridge->driver->agp_alloc_page();
if (addr == NULL)
return NULL;
new = agp_create_memory(1);
if (new == NULL)
return NULL;
new->memory[0] = virt_to_phys(addr);
new->page_count = 1;
new->num_scratch_pages = 1;
new->type = AGP_PHYS_MEMORY;
new->physical = new->memory[0];
return new;
}
static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type) static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
{ {
agp_memory *new; agp_memory *new;
if (type == AGP_DCACHE_MEMORY) { if (type == AGP_DCACHE_MEMORY) {
if (pg_count != intel_i810_private.num_dcache_entries) { if (pg_count != intel_i810_private.num_dcache_entries)
return NULL; return NULL;
}
new = agp_create_memory(1);
if (new == NULL) { new = agp_create_memory(1);
if (new == NULL)
return NULL; return NULL;
}
new->type = AGP_DCACHE_MEMORY; new->type = AGP_DCACHE_MEMORY;
new->page_count = pg_count; new->page_count = pg_count;
new->num_scratch_pages = 0; new->num_scratch_pages = 0;
vfree(new->memory); vfree(new->memory);
return new; return new;
} }
if(type == AGP_PHYS_MEMORY) { if (type == AGP_PHYS_MEMORY)
void *addr; return(alloc_agpphysmem_i8xx(pg_count, type));
/* The I810 requires a physical address to program
* it's mouse pointer into hardware. However the
* Xserver still writes to it through the agp
* aperture
*/
if (pg_count != 1)
return NULL;
new = agp_create_memory(1);
if (new == NULL)
return NULL;
addr = agp_bridge->agp_alloc_page();
if (addr == NULL) {
/* Free this structure */
agp_free_memory(new);
return NULL;
}
new->memory[0] = virt_to_phys(addr);
new->page_count = 1;
new->num_scratch_pages = 1;
new->type = AGP_PHYS_MEMORY;
new->physical = new->memory[0];
return new;
}
return NULL; return NULL;
} }
...@@ -237,7 +239,7 @@ static void intel_i810_free_by_type(agp_memory * curr) ...@@ -237,7 +239,7 @@ static void intel_i810_free_by_type(agp_memory * curr)
{ {
agp_free_key(curr->key); agp_free_key(curr->key);
if(curr->type == AGP_PHYS_MEMORY) { if(curr->type == AGP_PHYS_MEMORY) {
agp_bridge->agp_destroy_page(phys_to_virt(curr->memory[0])); agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[0]));
vfree(curr->memory); vfree(curr->memory);
} }
kfree(curr); kfree(curr);
...@@ -246,39 +248,7 @@ static void intel_i810_free_by_type(agp_memory * curr) ...@@ -246,39 +248,7 @@ static void intel_i810_free_by_type(agp_memory * curr)
static unsigned long intel_i810_mask_memory(unsigned long addr, int type) static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
{ {
/* Type checking must be done elsewhere */ /* Type checking must be done elsewhere */
return addr | agp_bridge->masks[type].mask; return addr | agp_bridge->driver->masks[type].mask;
}
static int __init intel_i810_setup(struct pci_dev *i810_dev)
{
intel_i810_private.i810_dev = i810_dev;
agp_bridge->masks = intel_i810_masks;
agp_bridge->aperture_sizes = (void *) intel_i810_sizes;
agp_bridge->size_type = FIXED_APER_SIZE;
agp_bridge->num_aperture_sizes = 2;
agp_bridge->dev_private_data = (void *) &intel_i810_private;
agp_bridge->needs_scratch_page = TRUE;
agp_bridge->configure = intel_i810_configure;
agp_bridge->fetch_size = intel_i810_fetch_size;
agp_bridge->cleanup = intel_i810_cleanup;
agp_bridge->tlb_flush = intel_i810_tlbflush;
agp_bridge->mask_memory = intel_i810_mask_memory;
agp_bridge->agp_enable = intel_i810_agp_enable;
agp_bridge->cache_flush = global_cache_flush;
agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
agp_bridge->insert_memory = intel_i810_insert_entries;
agp_bridge->remove_memory = intel_i810_remove_entries;
agp_bridge->alloc_by_type = intel_i810_alloc_by_type;
agp_bridge->free_by_type = intel_i810_free_by_type;
agp_bridge->agp_alloc_page = agp_generic_alloc_page;
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->suspend = agp_generic_suspend;
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
} }
static struct aper_size_info_fixed intel_i830_sizes[] = static struct aper_size_info_fixed intel_i830_sizes[] =
...@@ -379,10 +349,11 @@ static int intel_i830_create_gatt_table(void) ...@@ -379,10 +349,11 @@ static int intel_i830_create_gatt_table(void)
temp &= 0xfff80000; temp &= 0xfff80000;
intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096); intel_i830_private.registers = (volatile u8 *) ioremap(temp,128 * 4096);
if (!intel_i830_private.registers) return (-ENOMEM); if (!intel_i830_private.registers)
return (-ENOMEM);
temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000; temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
CACHE_FLUSH(); global_cache_flush();
/* we have to call this as early as possible after the MMIO base address is known */ /* we have to call this as early as possible after the MMIO base address is known */
intel_i830_init_gtt_entries(); intel_i830_init_gtt_entries();
...@@ -407,7 +378,7 @@ static int intel_i830_fetch_size(void) ...@@ -407,7 +378,7 @@ static int intel_i830_fetch_size(void)
u16 gmch_ctrl; u16 gmch_ctrl;
struct aper_size_info_fixed *values; struct aper_size_info_fixed *values;
values = A_SIZE_FIX(agp_bridge->aperture_sizes); values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB && if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) { agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
...@@ -449,9 +420,9 @@ static int intel_i830_configure(void) ...@@ -449,9 +420,9 @@ static int intel_i830_configure(void)
pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED); OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
CACHE_FLUSH(); global_cache_flush();
if (agp_bridge->needs_scratch_page == TRUE) if (agp_bridge->driver->needs_scratch_page)
for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page); OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
...@@ -490,15 +461,15 @@ static int intel_i830_insert_entries(agp_memory *mem,off_t pg_start,int type) ...@@ -490,15 +461,15 @@ static int intel_i830_insert_entries(agp_memory *mem,off_t pg_start,int type)
(mem->type != 0 && mem->type != AGP_PHYS_MEMORY)) (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
return (-EINVAL); return (-EINVAL);
CACHE_FLUSH(); global_cache_flush();
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4), OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),
agp_bridge->mask_memory(mem->memory[i], mem->type)); agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
CACHE_FLUSH(); global_cache_flush();
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return(0); return(0);
} }
...@@ -507,7 +478,7 @@ static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type) ...@@ -507,7 +478,7 @@ static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type)
{ {
int i; int i;
CACHE_FLUSH (); global_cache_flush();
if (pg_start < intel_i830_private.gtt_entries) { if (pg_start < intel_i830_private.gtt_entries) {
printk ("Trying to disable local/stolen memory\n"); printk ("Trying to disable local/stolen memory\n");
...@@ -517,90 +488,22 @@ static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type) ...@@ -517,90 +488,22 @@ static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type)
for (i = pg_start; i < (mem->page_count + pg_start); i++) for (i = pg_start; i < (mem->page_count + pg_start); i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page); OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
CACHE_FLUSH(); global_cache_flush();
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return (0); return (0);
} }
static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
{ {
agp_memory *nw; if (type == AGP_PHYS_MEMORY)
return(alloc_agpphysmem_i8xx(pg_count, type));
/* always return NULL for now */
if (type == AGP_DCACHE_MEMORY) return(NULL);
if (type == AGP_PHYS_MEMORY) {
void *addr;
/* The i830 requires a physical address to program
* it's mouse pointer into hardware. However the
* Xserver still writes to it through the agp
* aperture
*/
if (pg_count != 1) return(NULL);
nw = agp_create_memory(1);
if (nw == NULL) return(NULL);
addr = agp_bridge->agp_alloc_page();
if (addr == NULL) {
/* free this structure */
agp_free_memory(nw);
return(NULL);
}
nw->memory[0] = virt_to_phys(addr);
nw->page_count = 1;
nw->num_scratch_pages = 1;
nw->type = AGP_PHYS_MEMORY;
nw->physical = nw->memory[0];
return(nw);
}
/* always return NULL for other allocation types for now */
return(NULL); return(NULL);
} }
static int __init intel_i830_setup(struct pci_dev *i830_dev)
{
intel_i830_private.i830_dev = i830_dev;
agp_bridge->masks = intel_i810_masks;
agp_bridge->aperture_sizes = (void *) intel_i830_sizes;
agp_bridge->size_type = FIXED_APER_SIZE;
agp_bridge->num_aperture_sizes = 2;
agp_bridge->dev_private_data = (void *) &intel_i830_private;
agp_bridge->needs_scratch_page = TRUE;
agp_bridge->configure = intel_i830_configure;
agp_bridge->fetch_size = intel_i830_fetch_size;
agp_bridge->cleanup = intel_i830_cleanup;
agp_bridge->tlb_flush = intel_i810_tlbflush;
agp_bridge->mask_memory = intel_i810_mask_memory;
agp_bridge->agp_enable = intel_i810_agp_enable;
agp_bridge->cache_flush = global_cache_flush;
agp_bridge->create_gatt_table = intel_i830_create_gatt_table;
agp_bridge->free_gatt_table = intel_i830_free_gatt_table;
agp_bridge->insert_memory = intel_i830_insert_entries;
agp_bridge->remove_memory = intel_i830_remove_entries;
agp_bridge->alloc_by_type = intel_i830_alloc_by_type;
agp_bridge->free_by_type = intel_i810_free_by_type;
agp_bridge->agp_alloc_page = agp_generic_alloc_page;
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->suspend = agp_generic_suspend;
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return(0);
}
static int intel_fetch_size(void) static int intel_fetch_size(void)
{ {
int i; int i;
...@@ -608,9 +511,9 @@ static int intel_fetch_size(void) ...@@ -608,9 +511,9 @@ static int intel_fetch_size(void)
struct aper_size_info_16 *values; struct aper_size_info_16 *values;
pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp); pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
values = A_SIZE_16(agp_bridge->aperture_sizes); values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i); agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i; agp_bridge->aperture_size_idx = i;
...@@ -621,22 +524,14 @@ static int intel_fetch_size(void) ...@@ -621,22 +524,14 @@ static int intel_fetch_size(void)
return 0; return 0;
} }
static int intel_8xx_fetch_size(void) static int __intel_8xx_fetch_size(u8 temp)
{ {
int i; int i;
u8 temp;
struct aper_size_info_8 *values; struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp); values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
/* Intel 815 chipsets have a _weird_ APSIZE register with only
* one non-reserved bit, so mask the others out ... */
if (agp_bridge->type == INTEL_I815)
temp &= (1 << 3);
values = A_SIZE_8(agp_bridge->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -647,6 +542,25 @@ static int intel_8xx_fetch_size(void) ...@@ -647,6 +542,25 @@ static int intel_8xx_fetch_size(void)
return 0; return 0;
} }
static int intel_8xx_fetch_size(void)
{
u8 temp;
pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
return __intel_8xx_fetch_size(temp);
}
static int intel_815_fetch_size(void)
{
u8 temp;
/* Intel 815 chipsets have a _weird_ APSIZE register with only
* one non-reserved bit, so mask the others out ... */
pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
temp &= (1 << 3);
return __intel_8xx_fetch_size(temp);
}
static void intel_tlbflush(agp_memory * mem) static void intel_tlbflush(agp_memory * mem)
{ {
...@@ -991,7 +905,7 @@ static int intel_7505_configure(void) ...@@ -991,7 +905,7 @@ static int intel_7505_configure(void)
static unsigned long intel_mask_memory(unsigned long addr, int type) static unsigned long intel_mask_memory(unsigned long addr, int type)
{ {
/* Memory type is ignored */ /* Memory type is ignored */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static void intel_resume(void) static void intel_resume(void)
...@@ -1041,584 +955,485 @@ static struct aper_size_info_8 intel_830mp_sizes[4] = ...@@ -1041,584 +955,485 @@ static struct aper_size_info_8 intel_830mp_sizes[4] =
{32, 8192, 3, 56} {32, 8192, 3, 56}
}; };
static int __init intel_generic_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_generic_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_generic_masks,
agp_bridge->aperture_sizes = (void *) intel_generic_sizes; .aperture_sizes = intel_generic_sizes,
agp_bridge->size_type = U16_APER_SIZE; .size_type = U16_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 7,
agp_bridge->dev_private_data = NULL; .configure = intel_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = intel_fetch_size,
agp_bridge->configure = intel_configure; .cleanup = intel_cleanup,
agp_bridge->fetch_size = intel_fetch_size; .tlb_flush = intel_tlbflush,
agp_bridge->cleanup = intel_cleanup; .mask_memory = intel_mask_memory,
agp_bridge->tlb_flush = intel_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = intel_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = intel_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = intel_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_815_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_810_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_i810_masks,
agp_bridge->aperture_sizes = (void *) intel_815_sizes; .aperture_sizes = intel_i810_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = FIXED_APER_SIZE,
agp_bridge->num_aperture_sizes = 2; .num_aperture_sizes = 2,
agp_bridge->dev_private_data = NULL; .needs_scratch_page = TRUE,
agp_bridge->needs_scratch_page = FALSE; .configure = intel_i810_configure,
agp_bridge->configure = intel_815_configure; .fetch_size = intel_i810_fetch_size,
agp_bridge->fetch_size = intel_8xx_fetch_size; .cleanup = intel_i810_cleanup,
agp_bridge->cleanup = intel_8xx_cleanup; .tlb_flush = intel_i810_tlbflush,
agp_bridge->tlb_flush = intel_8xx_tlbflush; .mask_memory = intel_i810_mask_memory,
agp_bridge->mask_memory = intel_mask_memory; .agp_enable = intel_i810_agp_enable,
agp_bridge->agp_enable = agp_generic_enable; .cache_flush = global_cache_flush,
agp_bridge->cache_flush = global_cache_flush; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .insert_memory = intel_i810_insert_entries,
agp_bridge->insert_memory = agp_generic_insert_memory; .remove_memory = intel_i810_remove_entries,
agp_bridge->remove_memory = agp_generic_remove_memory; .alloc_by_type = intel_i810_alloc_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .free_by_type = intel_i810_free_by_type,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .suspend = agp_generic_suspend,
agp_bridge->suspend = agp_generic_suspend; .resume = agp_generic_resume,
agp_bridge->resume = agp_generic_resume; };
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_820_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_815_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_generic_masks,
agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; .aperture_sizes = intel_815_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = U8_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 2,
agp_bridge->dev_private_data = NULL; .configure = intel_815_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = intel_815_fetch_size,
agp_bridge->configure = intel_820_configure; .cleanup = intel_8xx_cleanup,
agp_bridge->fetch_size = intel_8xx_fetch_size; .tlb_flush = intel_8xx_tlbflush,
agp_bridge->cleanup = intel_820_cleanup; .mask_memory = intel_mask_memory,
agp_bridge->tlb_flush = intel_820_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = intel_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = agp_generic_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_830mp_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_830_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_i810_masks,
agp_bridge->aperture_sizes = (void *) intel_830mp_sizes; .aperture_sizes = intel_i830_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = FIXED_APER_SIZE,
agp_bridge->num_aperture_sizes = 4; .num_aperture_sizes = 2,
agp_bridge->dev_private_data = NULL; .needs_scratch_page = TRUE,
agp_bridge->needs_scratch_page = FALSE; .configure = intel_i830_configure,
agp_bridge->configure = intel_830mp_configure; .fetch_size = intel_i830_fetch_size,
agp_bridge->fetch_size = intel_8xx_fetch_size; .cleanup = intel_i830_cleanup,
agp_bridge->cleanup = intel_8xx_cleanup; .tlb_flush = intel_i810_tlbflush,
agp_bridge->tlb_flush = intel_8xx_tlbflush; .mask_memory = intel_i810_mask_memory,
agp_bridge->mask_memory = intel_mask_memory; .agp_enable = intel_i810_agp_enable,
agp_bridge->agp_enable = agp_generic_enable; .cache_flush = global_cache_flush,
agp_bridge->cache_flush = global_cache_flush; .create_gatt_table = intel_i830_create_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .free_gatt_table = intel_i830_free_gatt_table,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .insert_memory = intel_i830_insert_entries,
agp_bridge->insert_memory = agp_generic_insert_memory; .remove_memory = intel_i830_remove_entries,
agp_bridge->remove_memory = agp_generic_remove_memory; .alloc_by_type = intel_i830_alloc_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .free_by_type = intel_i810_free_by_type,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .suspend = agp_generic_suspend,
agp_bridge->suspend = agp_generic_suspend; .resume = agp_generic_resume,
agp_bridge->resume = agp_generic_resume; };
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_840_setup (struct pci_dev *pdev)
{
agp_bridge->masks = intel_generic_masks;
agp_bridge->aperture_sizes = (void *) intel_8xx_sizes;
agp_bridge->size_type = U8_APER_SIZE;
agp_bridge->num_aperture_sizes = 7;
agp_bridge->dev_private_data = NULL;
agp_bridge->needs_scratch_page = FALSE;
agp_bridge->configure = intel_840_configure;
agp_bridge->fetch_size = intel_8xx_fetch_size;
agp_bridge->cleanup = intel_8xx_cleanup;
agp_bridge->tlb_flush = intel_8xx_tlbflush;
agp_bridge->mask_memory = intel_mask_memory;
agp_bridge->agp_enable = agp_generic_enable;
agp_bridge->cache_flush = global_cache_flush;
agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
agp_bridge->insert_memory = agp_generic_insert_memory;
agp_bridge->remove_memory = agp_generic_remove_memory;
agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
agp_bridge->free_by_type = agp_generic_free_by_type;
agp_bridge->agp_alloc_page = agp_generic_alloc_page;
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->suspend = agp_generic_suspend;
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_845_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_820_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_generic_masks,
agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; .aperture_sizes = intel_8xx_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = U8_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 7,
agp_bridge->dev_private_data = NULL; .configure = intel_820_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = intel_8xx_fetch_size,
agp_bridge->configure = intel_845_configure; .cleanup = intel_820_cleanup,
agp_bridge->fetch_size = intel_8xx_fetch_size; .tlb_flush = intel_820_tlbflush,
agp_bridge->cleanup = intel_8xx_cleanup; .mask_memory = intel_mask_memory,
agp_bridge->tlb_flush = intel_8xx_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = intel_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = agp_generic_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = intel_845_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_850_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_830mp_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_generic_masks,
agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; .aperture_sizes = intel_830mp_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = U8_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 4,
agp_bridge->dev_private_data = NULL; .configure = intel_830mp_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = intel_8xx_fetch_size,
agp_bridge->configure = intel_850_configure; .cleanup = intel_8xx_cleanup,
agp_bridge->fetch_size = intel_8xx_fetch_size; .tlb_flush = intel_8xx_tlbflush,
agp_bridge->cleanup = intel_8xx_cleanup; .mask_memory = intel_mask_memory,
agp_bridge->tlb_flush = intel_8xx_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = intel_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = agp_generic_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_860_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_840_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_generic_masks,
agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; .aperture_sizes = intel_8xx_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = U8_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 7,
agp_bridge->dev_private_data = NULL; .configure = intel_840_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = intel_8xx_fetch_size,
agp_bridge->configure = intel_860_configure; .cleanup = intel_8xx_cleanup,
agp_bridge->fetch_size = intel_8xx_fetch_size; .tlb_flush = intel_8xx_tlbflush,
agp_bridge->cleanup = intel_8xx_cleanup; .mask_memory = intel_mask_memory,
agp_bridge->tlb_flush = intel_8xx_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = intel_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = agp_generic_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init intel_7505_setup (struct pci_dev *pdev) struct agp_bridge_driver intel_845_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = intel_generic_masks; .masks = intel_generic_masks,
agp_bridge->aperture_sizes = (void *) intel_8xx_sizes; .aperture_sizes = intel_8xx_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = U8_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 7,
agp_bridge->dev_private_data = NULL; .configure = intel_845_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = intel_8xx_fetch_size,
agp_bridge->configure = intel_7505_configure; .cleanup = intel_8xx_cleanup,
agp_bridge->fetch_size = intel_8xx_fetch_size; .tlb_flush = intel_8xx_tlbflush,
agp_bridge->cleanup = intel_8xx_cleanup; .mask_memory = intel_mask_memory,
agp_bridge->tlb_flush = intel_8xx_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = intel_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = intel_845_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0; struct agp_bridge_driver intel_850_driver = {
return 0; .owner = THIS_MODULE,
} .masks = intel_generic_masks,
struct agp_device_ids intel_agp_device_ids[] __initdata = .aperture_sizes = intel_8xx_sizes,
{ .size_type = U8_APER_SIZE,
{ .num_aperture_sizes = 7,
.device_id = PCI_DEVICE_ID_INTEL_82443LX_0, .configure = intel_850_configure,
.chipset = INTEL_LX, .fetch_size = intel_8xx_fetch_size,
.chipset_name = "440LX", .cleanup = intel_8xx_cleanup,
}, .tlb_flush = intel_8xx_tlbflush,
{ .mask_memory = intel_mask_memory,
.device_id = PCI_DEVICE_ID_INTEL_82443BX_0, .agp_enable = agp_generic_enable,
.chipset = INTEL_BX, .cache_flush = global_cache_flush,
.chipset_name = "440BX", .create_gatt_table = agp_generic_create_gatt_table,
}, .free_gatt_table = agp_generic_free_gatt_table,
{ .insert_memory = agp_generic_insert_memory,
.device_id = PCI_DEVICE_ID_INTEL_82443GX_0, .remove_memory = agp_generic_remove_memory,
.chipset = INTEL_GX, .alloc_by_type = agp_generic_alloc_by_type,
.chipset_name = "440GX", .free_by_type = agp_generic_free_by_type,
}, .agp_alloc_page = agp_generic_alloc_page,
{ .agp_destroy_page = agp_generic_destroy_page,
.device_id = PCI_DEVICE_ID_INTEL_82815_MC, .suspend = agp_generic_suspend,
.chipset = INTEL_I815, .resume = agp_generic_resume,
.chipset_name = "i815", };
.chipset_setup = intel_815_setup
}, struct agp_bridge_driver intel_860_driver = {
{ .owner = THIS_MODULE,
.device_id = PCI_DEVICE_ID_INTEL_82820_HB, .masks = intel_generic_masks,
.chipset = INTEL_I820, .aperture_sizes = intel_8xx_sizes,
.chipset_name = "i820", .size_type = U8_APER_SIZE,
.chipset_setup = intel_820_setup .num_aperture_sizes = 7,
}, .configure = intel_860_configure,
{ .fetch_size = intel_8xx_fetch_size,
.device_id = PCI_DEVICE_ID_INTEL_82820_UP_HB, .cleanup = intel_8xx_cleanup,
.chipset = INTEL_I820, .tlb_flush = intel_8xx_tlbflush,
.chipset_name = "i820", .mask_memory = intel_mask_memory,
.chipset_setup = intel_820_setup .agp_enable = agp_generic_enable,
}, .cache_flush = global_cache_flush,
{ .create_gatt_table = agp_generic_create_gatt_table,
.device_id = PCI_DEVICE_ID_INTEL_82830_HB, .free_gatt_table = agp_generic_free_gatt_table,
.chipset = INTEL_I830_M, .insert_memory = agp_generic_insert_memory,
.chipset_name = "830M", .remove_memory = agp_generic_remove_memory,
.chipset_setup = intel_830mp_setup .alloc_by_type = agp_generic_alloc_by_type,
}, .free_by_type = agp_generic_free_by_type,
{ .agp_alloc_page = agp_generic_alloc_page,
.device_id = PCI_DEVICE_ID_INTEL_82840_HB, .agp_destroy_page = agp_generic_destroy_page,
.chipset = INTEL_I840, .suspend = agp_generic_suspend,
.chipset_name = "i840", .resume = agp_generic_resume,
.chipset_setup = intel_840_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_82845_HB,
.chipset = INTEL_I845,
.chipset_name = "i845",
.chipset_setup = intel_845_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_82845G_HB,
.chipset = INTEL_I845_G,
.chipset_name = "845G",
.chipset_setup = intel_845_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_82850_HB,
.chipset = INTEL_I850,
.chipset_name = "i850",
.chipset_setup = intel_850_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_82855_HB,
.chipset = INTEL_I855_PM,
.chipset_name = "855PM",
.chipset_setup = intel_845_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_82860_HB,
.chipset = INTEL_I860,
.chipset_name = "i860",
.chipset_setup = intel_860_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_82865_HB,
.chipset = INTEL_I865_G,
.chipset_name = "865G",
.chipset_setup = intel_845_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_7505_0,
.chipset = INTEL_E7505,
.chipset_name = "E7505",
.chipset_setup = intel_7505_setup
},
{
.device_id = PCI_DEVICE_ID_INTEL_7205_0,
.chipset = INTEL_E7505,
.chipset_name = "E7205",
.chipset_setup = intel_7505_setup
},
{ }, /* dummy final entry, always present */
}; };
struct agp_bridge_driver intel_7505_driver = {
.owner = THIS_MODULE,
.masks = intel_generic_masks,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 7,
.configure = intel_7505_configure,
.fetch_size = intel_8xx_fetch_size,
.cleanup = intel_8xx_cleanup,
.tlb_flush = intel_8xx_tlbflush,
.mask_memory = intel_mask_memory,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.suspend = agp_generic_suspend,
.resume = agp_generic_resume,
};
/* scan table above for supported devices */ static int find_i810(u16 device, const char *name)
static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
{ {
int j=0; struct pci_dev *i810_dev;
struct agp_device_ids *devs;
devs = intel_agp_device_ids;
while (devs[j].chipset_name != NULL) {
if (pdev->device == devs[j].device_id) {
printk (KERN_INFO PFX "Detected Intel %s chipset\n",
devs[j].chipset_name);
agp_bridge->type = devs[j].chipset;
if (devs[j].chipset_setup != NULL)
return devs[j].chipset_setup(pdev);
else
return intel_generic_setup(pdev);
}
j++;
}
j--;
/* try init anyway, if user requests it */
if (agp_try_unsupported) {
printk(KERN_WARNING PFX "Trying generic Intel routines"
" for device id: %04x\n", pdev->device);
agp_bridge->type = INTEL_GENERIC;
return intel_generic_setup(pdev);
}
printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x)," i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, device, NULL);
" you might want to try agp_try_unsupported=1.\n", pdev->device); if (!i810_dev) {
return -ENODEV; printk(KERN_ERR PFX "Detected an Intel %s Chipset, "
"but could not find the secondary device.\n",
name);
return 0;
}
intel_i810_private.i810_dev = i810_dev;
return 1;
} }
static int find_i830(u16 device)
{
struct pci_dev *i830_dev;
i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL, device, NULL);
if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
device, i830_dev);
}
/* Supported Device Scanning routine */ if (!i830_dev)
return 0;
intel_i830_private.i830_dev = i830_dev;
return 1;
}
static int __init agp_find_supported_device(struct pci_dev *dev) static int __init agp_intel_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{ {
struct pci_dev *i810_dev; struct agp_bridge_data *bridge;
char *name = "(unknown)";
u8 cap_ptr = 0; u8 cap_ptr = 0;
agp_bridge->dev = dev; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
/* This shit needs moving into tables/init-routines. */ bridge = agp_alloc_bridge();
switch (dev->device) { if (!bridge)
case PCI_DEVICE_ID_INTEL_82810_MC1: return -ENOMEM;
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1, NULL);
if (i810_dev == NULL) {
printk(KERN_ERR PFX "Detected an Intel i810,"
" but could not find the secondary device.\n");
return -ENODEV;
}
printk(KERN_INFO PFX "Detected an Intel i810 Chipset.\n");
agp_bridge->type = INTEL_I810;
return intel_i810_setup (i810_dev);
switch (pdev->device) {
case PCI_DEVICE_ID_INTEL_82443LX_0:
bridge->driver = &intel_generic_driver;
name = "440LX";
break;
case PCI_DEVICE_ID_INTEL_82443BX_0:
bridge->driver = &intel_generic_driver;
name = "440BX";
break;
case PCI_DEVICE_ID_INTEL_82443GX_0:
bridge->driver = &intel_generic_driver;
name = "440GX";
break;
case PCI_DEVICE_ID_INTEL_82810_MC1:
if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG1, "i810"))
goto fail;
bridge->driver = &intel_810_driver;
name = "i810";
break;
case PCI_DEVICE_ID_INTEL_82810_MC3: case PCI_DEVICE_ID_INTEL_82810_MC3:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, NULL); if (!find_i810(PCI_DEVICE_ID_INTEL_82810_IG3, "i810 DC100"))
if (i810_dev == NULL) { goto fail;
printk(KERN_ERR PFX "Detected an Intel i810 DC100, but could not find the " bridge->driver = &intel_810_driver;
"secondary device.\n"); name = "i810 DC100";
return -ENODEV; break;
}
printk(KERN_INFO PFX "Detected an Intel i810 DC100 Chipset.\n");
agp_bridge->type = INTEL_I810;
return intel_i810_setup(i810_dev);
case PCI_DEVICE_ID_INTEL_82810E_MC: case PCI_DEVICE_ID_INTEL_82810E_MC:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG, NULL); if (!find_i810(PCI_DEVICE_ID_INTEL_82810E_IG, "i810 E"))
if (i810_dev == NULL) { goto fail;
printk(KERN_ERR PFX "Detected an Intel i810 E" bridge->driver = &intel_810_driver;
", but could not find the secondary device.\n"); name = "i810 E";
return -ENODEV; break;
}
printk(KERN_INFO PFX "Detected an Intel i810 E Chipset.\n");
agp_bridge->type = INTEL_I810;
return intel_i810_setup(i810_dev);
case PCI_DEVICE_ID_INTEL_82815_MC: case PCI_DEVICE_ID_INTEL_82815_MC:
/* The i815 can operate either as an i810 style /*
* The i815 can operate either as an i810 style
* integrated device, or as an AGP4X motherboard. * integrated device, or as an AGP4X motherboard.
*
* This only addresses the first mode:
*/ */
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, NULL); if (find_i810(PCI_DEVICE_ID_INTEL_82815_CGC, "i815"))
if (i810_dev == NULL) { bridge->driver = &intel_810_driver;
printk(KERN_ERR PFX "agpgart: Detected an " else
"Intel i815, but could not find the" bridge->driver = &intel_815_driver;
" secondary device. Assuming a " name = "i815";
"non-integrated video card.\n"); break;
break; case PCI_DEVICE_ID_INTEL_82820_HB:
} case PCI_DEVICE_ID_INTEL_82820_UP_HB:
printk(KERN_INFO PFX "agpgart: Detected an Intel i815 Chipset.\n"); bridge->driver = &intel_820_driver;
agp_bridge->type = INTEL_I810; name = "i820";
return intel_i810_setup(i810_dev); break;
case PCI_DEVICE_ID_INTEL_82845G_HB:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82845G_IG, NULL);
if (i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82845G_IG, i810_dev);
}
if (i810_dev == NULL) {
/*
* We probably have a I845G chipset with an external graphics
* card. It will be initialized later
*/
agp_bridge->type = INTEL_I845_G;
break;
}
printk(KERN_INFO PFX "Detected an Intel(R) 845G Chipset.\n");
agp_bridge->type = INTEL_I810;
return intel_i830_setup(i810_dev);
case PCI_DEVICE_ID_INTEL_82830_HB: case PCI_DEVICE_ID_INTEL_82830_HB:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82830_CGC, NULL); if (find_i830(PCI_DEVICE_ID_INTEL_82830_CGC)) {
if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) bridge->driver = &intel_830_driver;
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82830_CGC, i810_dev); } else {
bridge->driver = &intel_830mp_driver;
if (i810_dev == NULL) {
/* Intel 830MP with external graphic card */
/* It will be initialized later */
agp_bridge->type = INTEL_I830_M;
break;
} }
printk(KERN_INFO PFX "Detected an Intel(R) 830M Chipset.\n"); name = "830M";
agp_bridge->type = INTEL_I810; break;
return intel_i830_setup(i810_dev); case PCI_DEVICE_ID_INTEL_82840_HB:
bridge->driver = &intel_840_driver;
case PCI_DEVICE_ID_INTEL_82855_HB: name = "i840";
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855_IG, NULL); break;
if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0) case PCI_DEVICE_ID_INTEL_82845_HB:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855_IG, i810_dev); bridge->driver = &intel_845_driver;
name = "i845";
if (i810_dev == NULL) { break;
/* Intel 855PM with external graphic card */ case PCI_DEVICE_ID_INTEL_82845G_HB:
/* It will be initialized later */ if (find_i830(PCI_DEVICE_ID_INTEL_82845G_IG)) {
agp_bridge->type = INTEL_I855_PM; bridge->driver = &intel_830_driver;
break; } else {
bridge->driver = &intel_845_driver;
} }
{ name = "845G";
u32 capval = 0; break;
const char *name = "855GM/852GM"; case PCI_DEVICE_ID_INTEL_82850_HB:
pci_read_config_dword(dev, I85X_CAPID, &capval); bridge->driver = &intel_850_driver;
switch ((capval >> I85X_VARIANT_SHIFT) & name = "i850";
I85X_VARIANT_MASK) { break;
case I855_GME: case PCI_DEVICE_ID_INTEL_82855PM_HB:
name = "855GME"; bridge->driver = &intel_845_driver;
break; name = "855PM";
case I855_GM: break;
name = "855GM"; case PCI_DEVICE_ID_INTEL_82855GM_HB:
break; if (find_i830(PCI_DEVICE_ID_INTEL_82855GM_IG)) {
case I852_GME: bridge->driver = &intel_830_driver;
name = "852GME"; name = "855";
break; } else {
case I852_GM: bridge->driver = &intel_845_driver;
name = "852GM"; name = "855GM";
break;
}
printk(KERN_INFO PFX
"Detected an Intel(R) %s Chipset.\n", name);
} }
agp_bridge->type = INTEL_I810; break;
return intel_i830_setup(i810_dev); case PCI_DEVICE_ID_INTEL_82860_HB:
bridge->driver = &intel_860_driver;
name = "i860";
break;
case PCI_DEVICE_ID_INTEL_82865_HB: case PCI_DEVICE_ID_INTEL_82865_HB:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG)) {
PCI_DEVICE_ID_INTEL_82865_IG, NULL); bridge->driver = &intel_830_driver;
if (i810_dev && PCI_FUNC(i810_dev->devfn) != 0) { } else {
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, bridge->driver = &intel_845_driver;
PCI_DEVICE_ID_INTEL_82865_IG, i810_dev);
} }
name = "865";
if (i810_dev == NULL) { break;
/* case PCI_DEVICE_ID_INTEL_82875_HB:
* We probably have a 865G chipset with an external graphics bridge->driver = &intel_845_driver;
* card. It will be initialized later name = "i875";
*/ break;
agp_bridge->type = INTEL_I865_G; case PCI_DEVICE_ID_INTEL_7505_0:
break; bridge->driver = &intel_7505_driver;
} name = "E7505";
printk(KERN_INFO PFX "Detected an Intel(R) 865G Chipset.\n"); break;
agp_bridge->type = INTEL_I810; case PCI_DEVICE_ID_INTEL_7205_0:
return intel_i830_setup(i810_dev); bridge->driver = &intel_7505_driver;
name = "E7205";
break;
default: default:
if (!agp_try_unsupported) {
printk(KERN_ERR PFX
"Unsupported Intel chipset (device id: %04x),"
" you might want to try agp_try_unsupported=1.\n",
pdev->device);
return -ENODEV;
}
bridge->driver = &intel_generic_driver;
break; break;
} };
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); bridge->dev = pdev;
if (cap_ptr == 0) bridge->capndx = cap_ptr;
return -ENODEV;
agp_bridge->capndx = cap_ptr;
/* Fill in the mode register */ if (bridge->driver == &intel_810_driver)
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); bridge->dev_private_data = &intel_i810_private;
else if (bridge->driver == &intel_830_driver)
bridge->dev_private_data = &intel_i830_private;
/* probe for known chipsets */ printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
return agp_lookup_host_bridge(dev);
}
static struct agp_driver intel_agp_driver = { /* Fill in the mode register */
.owner = THIS_MODULE, pci_read_config_dword(pdev,
}; bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
fail:
agp_put_bridge(bridge);
return -ENODEV;
}
static int __init agp_intel_probe (struct pci_dev *dev, const struct pci_device_id *ent) static void __devexit agp_intel_remove(struct pci_dev *pdev)
{ {
if (agp_find_supported_device(dev) == 0) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
intel_agp_driver.dev = dev;
agp_register_driver(&intel_agp_driver); agp_remove_bridge(bridge);
return 0; agp_put_bridge(bridge);
}
return -ENODEV;
} }
static struct pci_device_id agp_intel_pci_table[] __initdata = { static struct pci_device_id agp_intel_pci_table[] __initdata = {
...@@ -1639,29 +1454,24 @@ static struct __initdata pci_driver agp_intel_pci_driver = { ...@@ -1639,29 +1454,24 @@ static struct __initdata pci_driver agp_intel_pci_driver = {
.name = "agpgart-intel", .name = "agpgart-intel",
.id_table = agp_intel_pci_table, .id_table = agp_intel_pci_table,
.probe = agp_intel_probe, .probe = agp_intel_probe,
.remove = agp_intel_remove,
}; };
/* intel_agp_init() must not be declared static for explicit /* intel_agp_init() must not be declared static for explicit
early initialization to work (ie i810fb) */ early initialization to work (ie i810fb) */
int __init agp_intel_init(void) int __init agp_intel_init(void)
{ {
int ret_val;
static int agp_initialised=0; static int agp_initialised=0;
if (agp_initialised==1) if (agp_initialised == 1)
return 0; return 0;
agp_initialised=1; agp_initialised=1;
ret_val = pci_module_init(&agp_intel_pci_driver); return pci_module_init(&agp_intel_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_intel_cleanup(void) static void __exit agp_intel_cleanup(void)
{ {
agp_unregister_driver(&intel_agp_driver);
pci_unregister_driver(&agp_intel_pci_driver); pci_unregister_driver(&agp_intel_pci_driver);
} }
......
/*
* Nvidia AGPGART routines.
* Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up
* to work in 2.5 by Dave Jones <davej@codemonkey.org.uk>
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
#include "agp.h"
/* registers */
#define NVIDIA_0_APBASE 0x10
#define NVIDIA_0_APSIZE 0x80
#define NVIDIA_1_WBC 0xf0
#define NVIDIA_2_GARTCTRL 0xd0
#define NVIDIA_2_APBASE 0xd8
#define NVIDIA_2_APLIMIT 0xdc
#define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4)
#define NVIDIA_3_APBASE 0x50
#define NVIDIA_3_APLIMIT 0x54
static int agp_try_unsupported __initdata = 0;
static struct _nvidia_private {
struct pci_dev *dev_1;
struct pci_dev *dev_2;
struct pci_dev *dev_3;
volatile u32 *aperture;
int num_active_entries;
off_t pg_offset;
u32 wbc_mask;
} nvidia_private;
static int nvidia_fetch_size(void)
{
int i;
u8 size_value;
struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE, &size_value);
size_value &= 0x0f;
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (size_value == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static int nvidia_configure(void)
{
int i, num_dirs;
u32 apbase, aplimit;
struct aper_size_info_8 *current_size;
u32 temp;
current_size = A_SIZE_8(agp_bridge->current_size);
/* aperture size */
pci_write_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge->dev, NVIDIA_0_APBASE, &apbase);
apbase &= PCI_BASE_ADDRESS_MEM_MASK;
agp_bridge->gart_bus_addr = apbase;
aplimit = apbase + (current_size->size * 1024 * 1024) - 1;
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APBASE, apbase);
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APLIMIT, aplimit);
pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APBASE, apbase);
pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APLIMIT, aplimit);
/* directory size is 64k */
num_dirs = current_size->size / 64;
nvidia_private.num_active_entries = current_size->num_entries;
nvidia_private.pg_offset = 0;
if (num_dirs == 0) {
num_dirs = 1;
nvidia_private.num_active_entries /= (64 / current_size->size);
nvidia_private.pg_offset = (apbase & (64 * 1024 * 1024 - 1) &
~(current_size->size * 1024 * 1024 - 1)) / PAGE_SIZE;
}
/* attbase */
for(i = 0; i < 8; i++) {
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_ATTBASE(i),
(agp_bridge->gatt_bus_addr + (i % num_dirs) * 64 * 1024) | 1);
}
/* gtlb control */
pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp);
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, temp | 0x11);
/* gart control */
pci_read_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, &temp);
pci_write_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, temp | 0x100);
/* map aperture */
nvidia_private.aperture =
(volatile u32 *) ioremap(apbase, 33 * PAGE_SIZE);
return 0;
}
static void nvidia_cleanup(void)
{
struct aper_size_info_8 *previous_size;
u32 temp;
/* gart control */
pci_read_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, &temp);
pci_write_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, temp & ~(0x100));
/* gtlb control */
pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp);
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, temp & ~(0x11));
/* unmap aperture */
iounmap((void *) nvidia_private.aperture);
/* restore previous aperture size */
previous_size = A_SIZE_8(agp_bridge->previous_size);
pci_write_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE,
previous_size->size_value);
}
static unsigned long nvidia_mask_memory(unsigned long addr, int type)
{
/* Memory type is ignored */
return addr | agp_bridge->driver->masks[0].mask;
}
#if 0
extern int agp_memory_reserved;
static int nvidia_insert_memory(agp_memory * mem, off_t pg_start, int type)
{
int i, j;
if ((type != 0) || (mem->type != 0))
return -EINVAL;
if ((pg_start + mem->page_count) >
(nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE))
return -EINVAL;
for(j = pg_start; j < (pg_start + mem->page_count); j++) {
if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[nvidia_private.pg_offset + j]))
return -EBUSY;
}
if (mem->is_flushed == FALSE) {
global_cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
agp_bridge->gatt_table[nvidia_private.pg_offset + j] = mem->memory[i];
agp_bridge->tlb_flush(mem);
return 0;
}
static int nvidia_remove_memory(agp_memory * mem, off_t pg_start, int type)
{
int i;
if ((type != 0) || (mem->type != 0))
return -EINVAL;
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
agp_bridge->gatt_table[nvidia_private.pg_offset + i] =
(unsigned long) agp_bridge->scratch_page;
}
agp_bridge->tlb_flush(mem);
return 0;
}
#endif
static void nvidia_tlbflush(agp_memory * mem)
{
unsigned long end;
u32 wbc_reg, temp;
int i;
/* flush chipset */
if (nvidia_private.wbc_mask) {
pci_read_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, &wbc_reg);
wbc_reg |= nvidia_private.wbc_mask;
pci_write_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, wbc_reg);
end = jiffies + 3*HZ;
do {
pci_read_config_dword(nvidia_private.dev_1,
NVIDIA_1_WBC, &wbc_reg);
if ((signed)(end - jiffies) <= 0) {
printk(KERN_ERR
"TLB flush took more than 3 seconds.\n");
}
} while (wbc_reg & nvidia_private.wbc_mask);
}
/* flush TLB entries */
for(i = 0; i < 32 + 1; i++)
temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)];
for(i = 0; i < 32 + 1; i++)
temp = nvidia_private.aperture[i * PAGE_SIZE / sizeof(u32)];
}
static struct aper_size_info_8 nvidia_generic_sizes[5] =
{
{512, 131072, 7, 0},
{256, 65536, 6, 8},
{128, 32768, 5, 12},
{64, 16384, 4, 14},
/* The 32M mode still requires a 64k gatt */
{32, 16384, 4, 15}
};
static struct gatt_mask nvidia_generic_masks[] =
{
{0x00000001, 0}
};
struct agp_bridge_driver nvidia_driver = {
.owner = THIS_MODULE,
.masks = nvidia_generic_masks,
.aperture_sizes = nvidia_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 5,
.configure = nvidia_configure,
.fetch_size = nvidia_fetch_size,
.cleanup = nvidia_cleanup,
.tlb_flush = nvidia_tlbflush,
.mask_memory = nvidia_mask_memory,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.suspend = agp_generic_suspend,
.resume = agp_generic_resume,
};
static int __init agp_nvidia_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
nvidia_private.dev_1 =
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1));
nvidia_private.dev_2 =
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
nvidia_private.dev_3 =
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));
if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) {
printk(KERN_INFO PFX "agpgart: Detected an NVIDIA "
"nForce/nForce2 chipset, but could not find "
"the secondary devices.\n");
return -ENODEV;
}
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
switch (pdev->device) {
case PCI_DEVICE_ID_NVIDIA_NFORCE:
printk(KERN_INFO PFX "Detected NVIDIA nForce chipset\n");
nvidia_private.wbc_mask = 0x00010000;
break;
case PCI_DEVICE_ID_NVIDIA_NFORCE2:
printk(KERN_INFO PFX "Detected NVIDIA nForce2 chipset\n");
nvidia_private.wbc_mask = 0x80000000;
break;
default:
if (!agp_try_unsupported) {
printk(KERN_ERR PFX
"Unsupported NVIDIA chipset (device id: %04x),"
" you might want to try agp_try_unsupported=1.\n",
pdev->device);
return -ENODEV;
}
printk(KERN_WARNING PFX
"Trying generic NVIDIA routines for device id: %04x\n",
pdev->device);
break;
}
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &nvidia_driver;
bridge->dev_private_data = &nvidia_private,
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_nvidia_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_nvidia_pci_table[] __initdata = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table);
static struct __initdata pci_driver agp_nvidia_pci_driver = {
.name = "agpgart-nvidia",
.id_table = agp_nvidia_pci_table,
.probe = agp_nvidia_probe,
.remove = agp_nvidia_remove,
};
static int __init agp_nvidia_init(void)
{
return pci_module_init(&agp_nvidia_pci_driver);
}
static void __exit agp_nvidia_cleanup(void)
{
pci_unregister_driver(&agp_nvidia_pci_driver);
}
module_init(agp_nvidia_init);
module_exit(agp_nvidia_cleanup);
MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("NVIDIA Corporation");
...@@ -17,8 +17,8 @@ static int sis_fetch_size(void) ...@@ -17,8 +17,8 @@ static int sis_fetch_size(void)
struct aper_size_info_8 *values; struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, SIS_APSIZE, &temp_size); pci_read_config_byte(agp_bridge->dev, SIS_APSIZE, &temp_size);
values = A_SIZE_8(agp_bridge->aperture_sizes); values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if ((temp_size == values[i].size_value) || if ((temp_size == values[i].size_value) ||
((temp_size & ~(0x03)) == ((temp_size & ~(0x03)) ==
(values[i].size_value & ~(0x03)))) { (values[i].size_value & ~(0x03)))) {
...@@ -67,7 +67,7 @@ static unsigned long sis_mask_memory(unsigned long addr, int type) ...@@ -67,7 +67,7 @@ static unsigned long sis_mask_memory(unsigned long addr, int type)
{ {
/* Memory type is ignored */ /* Memory type is ignored */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static struct aper_size_info_8 sis_generic_sizes[7] = static struct aper_size_info_8 sis_generic_sizes[7] =
...@@ -86,164 +86,144 @@ static struct gatt_mask sis_generic_masks[] = ...@@ -86,164 +86,144 @@ static struct gatt_mask sis_generic_masks[] =
{.mask = 0x00000000, .type = 0} {.mask = 0x00000000, .type = 0}
}; };
static int __init sis_generic_setup (struct pci_dev *pdev) struct agp_bridge_driver sis_driver = {
{ .owner = THIS_MODULE,
agp_bridge->masks = sis_generic_masks; .masks = sis_generic_masks,
agp_bridge->aperture_sizes = (void *) sis_generic_sizes; .aperture_sizes = sis_generic_sizes,
agp_bridge->size_type = U8_APER_SIZE; .size_type = U8_APER_SIZE,
agp_bridge->num_aperture_sizes = 7; .num_aperture_sizes = 7,
agp_bridge->dev_private_data = NULL; .configure = sis_configure,
agp_bridge->needs_scratch_page = FALSE; .fetch_size = sis_fetch_size,
agp_bridge->configure = sis_configure; .cleanup = sis_cleanup,
agp_bridge->fetch_size = sis_fetch_size; .tlb_flush = sis_tlbflush,
agp_bridge->cleanup = sis_cleanup; .mask_memory = sis_mask_memory,
agp_bridge->tlb_flush = sis_tlbflush; .agp_enable = agp_generic_enable,
agp_bridge->mask_memory = sis_mask_memory; .cache_flush = global_cache_flush,
agp_bridge->agp_enable = agp_generic_enable; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->cache_flush = global_cache_flush; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .insert_memory = agp_generic_insert_memory,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .remove_memory = agp_generic_remove_memory,
agp_bridge->insert_memory = agp_generic_insert_memory; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->remove_memory = agp_generic_remove_memory; .free_by_type = agp_generic_free_by_type,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->free_by_type = agp_generic_free_by_type; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; .suspend = agp_generic_suspend,
agp_bridge->agp_destroy_page = agp_generic_destroy_page; .resume = agp_generic_resume,
agp_bridge->suspend = agp_generic_suspend; };
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
struct agp_device_ids sis_agp_device_ids[] __initdata = struct agp_device_ids sis_agp_device_ids[] __initdata =
{ {
{ {
.device_id = PCI_DEVICE_ID_SI_740, .device_id = PCI_DEVICE_ID_SI_740,
.chipset = SIS_GENERIC,
.chipset_name = "740", .chipset_name = "740",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_650, .device_id = PCI_DEVICE_ID_SI_650,
.chipset = SIS_GENERIC,
.chipset_name = "650", .chipset_name = "650",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_651, .device_id = PCI_DEVICE_ID_SI_651,
.chipset = SIS_GENERIC,
.chipset_name = "651", .chipset_name = "651",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_645, .device_id = PCI_DEVICE_ID_SI_645,
.chipset = SIS_GENERIC,
.chipset_name = "645", .chipset_name = "645",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_646, .device_id = PCI_DEVICE_ID_SI_646,
.chipset = SIS_GENERIC,
.chipset_name = "646", .chipset_name = "646",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_735, .device_id = PCI_DEVICE_ID_SI_735,
.chipset = SIS_GENERIC,
.chipset_name = "735", .chipset_name = "735",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_745, .device_id = PCI_DEVICE_ID_SI_745,
.chipset = SIS_GENERIC,
.chipset_name = "745", .chipset_name = "745",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_730, .device_id = PCI_DEVICE_ID_SI_730,
.chipset = SIS_GENERIC,
.chipset_name = "730", .chipset_name = "730",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_630, .device_id = PCI_DEVICE_ID_SI_630,
.chipset = SIS_GENERIC,
.chipset_name = "630", .chipset_name = "630",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_540, .device_id = PCI_DEVICE_ID_SI_540,
.chipset = SIS_GENERIC,
.chipset_name = "540", .chipset_name = "540",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_620, .device_id = PCI_DEVICE_ID_SI_620,
.chipset = SIS_GENERIC,
.chipset_name = "620", .chipset_name = "620",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_530, .device_id = PCI_DEVICE_ID_SI_530,
.chipset = SIS_GENERIC,
.chipset_name = "530", .chipset_name = "530",
}, },
{ {
.device_id = PCI_DEVICE_ID_SI_550, .device_id = PCI_DEVICE_ID_SI_550,
.chipset = SIS_GENERIC,
.chipset_name = "550", .chipset_name = "550",
}, },
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
/* scan table above for supported devices */ static int __init agp_sis_probe(struct pci_dev *pdev,
static int __init agp_lookup_host_bridge (struct pci_dev *pdev) const struct pci_device_id *ent)
{ {
int j=0; struct agp_device_ids *devs = sis_agp_device_ids;
struct agp_device_ids *devs; struct agp_bridge_data *bridge;
u8 cap_ptr;
devs = sis_agp_device_ids; int j;
while (devs[j].chipset_name != NULL) { cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
/* probe for known chipsets */
for (j = 0; devs[j].chipset_name; j++) {
if (pdev->device == devs[j].device_id) { if (pdev->device == devs[j].device_id) {
printk (KERN_INFO PFX "Detected SiS %s chipset\n", printk(KERN_INFO PFX "Detected SiS %s chipset\n",
devs[j].chipset_name); devs[j].chipset_name);
agp_bridge->type = devs[j].chipset; goto found;
if (devs[j].chipset_setup != NULL)
return devs[j].chipset_setup(pdev);
else
return sis_generic_setup(pdev);
} }
j++;
} }
/* try init anyway, if user requests it */ if (!agp_try_unsupported) {
if (agp_try_unsupported) { printk(KERN_ERR PFX
printk(KERN_WARNING PFX "Trying generic SiS routines" "Unsupported SiS chipset (device id: %04x),"
" for device id: %04x\n", pdev->device); " you might want to try agp_try_unsupported=1.\n",
agp_bridge->type = SIS_GENERIC; pdev->device);
return sis_generic_setup(pdev); return -ENODEV;
} }
printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)," printk(KERN_WARNING PFX "Trying generic SiS routines"
" you might want to try agp_try_unsupported=1.\n", pdev->device); " for device id: %04x\n", pdev->device);
return -ENODEV;
}
static struct agp_driver sis_agp_driver = { found:
.owner = THIS_MODULE, bridge = agp_alloc_bridge();
}; if (!bridge)
return -ENOMEM;
static int __init agp_sis_probe (struct pci_dev *dev, const struct pci_device_id *ent) bridge->driver = &sis_driver;
{ bridge->dev = pdev;
u8 cap_ptr = 0; bridge->capndx = cap_ptr;
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); /* Fill in the mode register */
if (cap_ptr == 0) pci_read_config_dword(pdev,
return -ENODEV; bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
/* probe for known chipsets */ pci_set_drvdata(pdev, bridge);
if (agp_lookup_host_bridge(dev) != -ENODEV) { return agp_add_bridge(bridge);
agp_bridge->dev = dev; }
agp_bridge->capndx = cap_ptr;
/* Fill in the mode register */ static void __devexit agp_sis_remove(struct pci_dev *pdev)
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); {
sis_agp_driver.dev = dev; struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_register_driver(&sis_agp_driver);
return 0; agp_remove_bridge(bridge);
} agp_put_bridge(bridge);
return -ENODEV;
} }
static struct pci_device_id agp_sis_pci_table[] __initdata = { static struct pci_device_id agp_sis_pci_table[] __initdata = {
...@@ -264,22 +244,16 @@ static struct __initdata pci_driver agp_sis_pci_driver = { ...@@ -264,22 +244,16 @@ static struct __initdata pci_driver agp_sis_pci_driver = {
.name = "agpgart-sis", .name = "agpgart-sis",
.id_table = agp_sis_pci_table, .id_table = agp_sis_pci_table,
.probe = agp_sis_probe, .probe = agp_sis_probe,
.remove = agp_sis_remove,
}; };
static int __init agp_sis_init(void) static int __init agp_sis_init(void)
{ {
int ret_val; return pci_module_init(&agp_sis_pci_driver);
ret_val = pci_module_init(&agp_sis_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_sis_cleanup(void) static void __exit agp_sis_cleanup(void)
{ {
agp_unregister_driver(&sis_agp_driver);
pci_unregister_driver(&agp_sis_pci_driver); pci_unregister_driver(&agp_sis_pci_driver);
} }
......
...@@ -35,7 +35,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) ...@@ -35,7 +35,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map)
return -ENOMEM; return -ENOMEM;
} }
SetPageReserved(virt_to_page(page_map->real)); SetPageReserved(virt_to_page(page_map->real));
CACHE_FLUSH(); global_cache_flush();
page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
PAGE_SIZE); PAGE_SIZE);
if (page_map->remapped == NULL) { if (page_map->remapped == NULL) {
...@@ -44,7 +44,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) ...@@ -44,7 +44,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map)
page_map->real = NULL; page_map->real = NULL;
return -ENOMEM; return -ENOMEM;
} }
CACHE_FLUSH(); global_cache_flush();
for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) { for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
page_map->remapped[i] = agp_bridge->scratch_page; page_map->remapped[i] = agp_bridge->scratch_page;
...@@ -203,7 +203,7 @@ static int serverworks_fetch_size(void) ...@@ -203,7 +203,7 @@ static int serverworks_fetch_size(void)
u32 temp2; u32 temp2;
struct aper_size_info_lvl2 *values; struct aper_size_info_lvl2 *values;
values = A_SIZE_LVL2(agp_bridge->aperture_sizes); values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp); pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp);
pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs, pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,
SVWRKS_SIZE_MASK); SVWRKS_SIZE_MASK);
...@@ -211,7 +211,7 @@ static int serverworks_fetch_size(void) ...@@ -211,7 +211,7 @@ static int serverworks_fetch_size(void)
pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp); pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp);
temp2 &= SVWRKS_SIZE_MASK; temp2 &= SVWRKS_SIZE_MASK;
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp2 == values[i].size_value) { if (temp2 == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -224,6 +224,37 @@ static int serverworks_fetch_size(void) ...@@ -224,6 +224,37 @@ static int serverworks_fetch_size(void)
return 0; return 0;
} }
/*
* This routine could be implemented by taking the addresses
* written to the GATT, and flushing them individually. However
* currently it just flushes the whole table. Which is probably
* more efficent, since agp_memory blocks can be a large number of
* entries.
*/
static void serverworks_tlbflush(agp_memory * temp)
{
unsigned long end;
OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 0x01);
end = jiffies + 3*HZ;
while(INREG8(serverworks_private.registers,
SVWRKS_POSTFLUSH) == 0x01) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "Posted write buffer flush took more"
"then 3 seconds\n");
}
}
OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 0x00000001);
end = jiffies + 3*HZ;
while(INREG32(serverworks_private.registers,
SVWRKS_DIRFLUSH) == 0x00000001) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "TLB flush took more"
"then 3 seconds\n");
}
}
}
static int serverworks_configure(void) static int serverworks_configure(void)
{ {
struct aper_size_info_lvl2 *current_size; struct aper_size_info_lvl2 *current_size;
...@@ -253,7 +284,7 @@ static int serverworks_configure(void) ...@@ -253,7 +284,7 @@ static int serverworks_configure(void)
enable_reg |= 0x1; /* Agp Enable bit */ enable_reg |= 0x1; /* Agp Enable bit */
pci_write_config_byte(serverworks_private.svrwrks_dev, pci_write_config_byte(serverworks_private.svrwrks_dev,
SVWRKS_AGP_ENABLE, enable_reg); SVWRKS_AGP_ENABLE, enable_reg);
agp_bridge->tlb_flush(NULL); serverworks_tlbflush(NULL);
agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP); agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP);
...@@ -277,43 +308,11 @@ static void serverworks_cleanup(void) ...@@ -277,43 +308,11 @@ static void serverworks_cleanup(void)
iounmap((void *) serverworks_private.registers); iounmap((void *) serverworks_private.registers);
} }
/*
* This routine could be implemented by taking the addresses
* written to the GATT, and flushing them individually. However
* currently it just flushes the whole table. Which is probably
* more efficent, since agp_memory blocks can be a large number of
* entries.
*/
static void serverworks_tlbflush(agp_memory * temp)
{
unsigned long end;
OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 0x01);
end = jiffies + 3*HZ;
while(INREG8(serverworks_private.registers,
SVWRKS_POSTFLUSH) == 0x01) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "Posted write buffer flush took more"
"then 3 seconds\n");
}
}
OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 0x00000001);
end = jiffies + 3*HZ;
while(INREG32(serverworks_private.registers,
SVWRKS_DIRFLUSH) == 0x00000001) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "TLB flush took more"
"then 3 seconds\n");
}
}
}
static unsigned long serverworks_mask_memory(unsigned long addr, int type) static unsigned long serverworks_mask_memory(unsigned long addr, int type)
{ {
/* Only type 0 is supported by the serverworks chipsets */ /* Only type 0 is supported by the serverworks chipsets */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static int serverworks_insert_memory(agp_memory * mem, static int serverworks_insert_memory(agp_memory * mem,
...@@ -336,14 +335,14 @@ static int serverworks_insert_memory(agp_memory * mem, ...@@ -336,14 +335,14 @@ static int serverworks_insert_memory(agp_memory * mem,
while (j < (pg_start + mem->page_count)) { while (j < (pg_start + mem->page_count)) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(addr); cur_gatt = SVRWRKS_GET_GATT(addr);
if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) { if (!PGE_EMPTY(agp_bridge, cur_gatt[GET_GATT_OFF(addr)])) {
return -EBUSY; return -EBUSY;
} }
j++; j++;
} }
if (mem->is_flushed == FALSE) { if (mem->is_flushed == FALSE) {
CACHE_FLUSH(); global_cache_flush();
mem->is_flushed = TRUE; mem->is_flushed = TRUE;
} }
...@@ -351,9 +350,9 @@ static int serverworks_insert_memory(agp_memory * mem, ...@@ -351,9 +350,9 @@ static int serverworks_insert_memory(agp_memory * mem,
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(addr); cur_gatt = SVRWRKS_GET_GATT(addr);
cur_gatt[GET_GATT_OFF(addr)] = cur_gatt[GET_GATT_OFF(addr)] =
agp_bridge->mask_memory(mem->memory[i], mem->type); agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
} }
agp_bridge->tlb_flush(mem); serverworks_tlbflush(mem);
return 0; return 0;
} }
...@@ -368,8 +367,8 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start, ...@@ -368,8 +367,8 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start,
return -EINVAL; return -EINVAL;
} }
CACHE_FLUSH(); global_cache_flush();
agp_bridge->tlb_flush(mem); serverworks_tlbflush(mem);
for (i = pg_start; i < (mem->page_count + pg_start); i++) { for (i = pg_start; i < (mem->page_count + pg_start); i++) {
addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
...@@ -378,7 +377,7 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start, ...@@ -378,7 +377,7 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start,
(unsigned long) agp_bridge->scratch_page; (unsigned long) agp_bridge->scratch_page;
} }
agp_bridge->tlb_flush(mem); serverworks_tlbflush(mem);
return 0; return 0;
} }
...@@ -420,123 +419,103 @@ static void serverworks_agp_enable(u32 mode) ...@@ -420,123 +419,103 @@ static void serverworks_agp_enable(u32 mode)
agp_device_command(command, 0); agp_device_command(command, 0);
} }
static int __init serverworks_setup (struct pci_dev *pdev) struct agp_bridge_driver sworks_driver = {
.owner = THIS_MODULE,
.masks = serverworks_masks,
.aperture_sizes = serverworks_sizes,
.size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7,
.configure = serverworks_configure,
.fetch_size = serverworks_fetch_size,
.cleanup = serverworks_cleanup,
.tlb_flush = serverworks_tlbflush,
.mask_memory = serverworks_mask_memory,
.agp_enable = serverworks_agp_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = serverworks_create_gatt_table,
.free_gatt_table = serverworks_free_gatt_table,
.insert_memory = serverworks_insert_memory,
.remove_memory = serverworks_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.suspend = agp_generic_suspend,
.resume = agp_generic_resume,
};
static int __init agp_serverworks_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{ {
u32 temp; struct agp_bridge_data *bridge;
u32 temp2; struct pci_dev *bridge_dev;
u32 temp, temp2;
serverworks_private.svrwrks_dev = pdev; /* Everything is on func 1 here so we are hardcoding function one */
bridge_dev = pci_find_slot((unsigned int)pdev->bus->number,
agp_bridge->masks = serverworks_masks; PCI_DEVFN(0, 1));
agp_bridge->aperture_sizes = (void *) serverworks_sizes; if (!bridge_dev) {
agp_bridge->size_type = LVL2_APER_SIZE; printk(KERN_INFO PFX "agpgart: Detected a Serverworks "
agp_bridge->num_aperture_sizes = 7; "Chipset, but could not find the secondary "
agp_bridge->dev_private_data = (void *) &serverworks_private; "device.\n");
agp_bridge->needs_scratch_page = TRUE; return -ENODEV;
agp_bridge->configure = serverworks_configure; }
agp_bridge->fetch_size = serverworks_fetch_size;
agp_bridge->cleanup = serverworks_cleanup;
agp_bridge->tlb_flush = serverworks_tlbflush;
agp_bridge->mask_memory = serverworks_mask_memory;
agp_bridge->agp_enable = serverworks_agp_enable;
agp_bridge->cache_flush = global_cache_flush;
agp_bridge->create_gatt_table = serverworks_create_gatt_table;
agp_bridge->free_gatt_table = serverworks_free_gatt_table;
agp_bridge->insert_memory = serverworks_insert_memory;
agp_bridge->remove_memory = serverworks_remove_memory;
agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
agp_bridge->free_by_type = agp_generic_free_by_type;
agp_bridge->agp_alloc_page = agp_generic_alloc_page;
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->suspend = agp_generic_suspend;
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
pci_read_config_dword(agp_bridge->dev,
SVWRKS_APSIZE,
&temp);
serverworks_private.gart_addr_ofs = 0x10; switch (pdev->device) {
case PCI_DEVICE_ID_SERVERWORKS_HE:
case PCI_DEVICE_ID_SERVERWORKS_LE:
case 0x0007:
break;
default:
if (!agp_try_unsupported)
return -ENODEV;
break;
}
if(temp & PCI_BASE_ADDRESS_MEM_TYPE_64) { serverworks_private.svrwrks_dev = bridge_dev;
pci_read_config_dword(agp_bridge->dev, serverworks_private.gart_addr_ofs = 0x10;
SVWRKS_APSIZE + 4,
&temp2); pci_read_config_dword(pdev, SVWRKS_APSIZE, &temp);
if(temp2 != 0) { if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
pci_read_config_dword(pdev, SVWRKS_APSIZE + 4, &temp2);
if (temp2 != 0) {
printk("Detected 64 bit aperture address, but top " printk("Detected 64 bit aperture address, but top "
"bits are not zero. Disabling agp\n"); "bits are not zero. Disabling agp\n");
return -ENODEV; return -ENODEV;
} }
serverworks_private.mm_addr_ofs = 0x18; serverworks_private.mm_addr_ofs = 0x18;
} else { } else
serverworks_private.mm_addr_ofs = 0x14; serverworks_private.mm_addr_ofs = 0x14;
}
pci_read_config_dword(agp_bridge->dev, pci_read_config_dword(pdev, serverworks_private.mm_addr_ofs, &temp);
serverworks_private.mm_addr_ofs, if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
&temp); pci_read_config_dword(pdev,
if(temp & PCI_BASE_ADDRESS_MEM_TYPE_64) { serverworks_private.mm_addr_ofs + 4, &temp2);
pci_read_config_dword(agp_bridge->dev, if (temp2 != 0) {
serverworks_private.mm_addr_ofs + 4,
&temp2);
if(temp2 != 0) {
printk("Detected 64 bit MMIO address, but top " printk("Detected 64 bit MMIO address, but top "
"bits are not zero. Disabling agp\n"); "bits are not zero. Disabling agp\n");
return -ENODEV; return -ENODEV;
} }
} }
return 0; bridge = agp_alloc_bridge();
} if (!bridge)
return -ENOMEM;
static int __init agp_find_supported_device(struct pci_dev *dev)
{
struct pci_dev *bridge_dev;
/* Everything is on func 1 here so we are hardcoding function one */
bridge_dev = pci_find_slot ((unsigned int)dev->bus->number, PCI_DEVFN(0, 1));
if(bridge_dev == NULL) {
printk(KERN_INFO PFX "agpgart: Detected a Serverworks "
"Chipset, but could not find the secondary "
"device.\n");
return -ENODEV;
}
agp_bridge->dev = dev;
switch (dev->device) {
case PCI_DEVICE_ID_SERVERWORKS_HE:
agp_bridge->type = SVWRKS_HE;
return serverworks_setup(bridge_dev);
case PCI_DEVICE_ID_SERVERWORKS_LE: bridge->driver = &sworks_driver;
case 0x0007: bridge->dev_private_data = &serverworks_private,
agp_bridge->type = SVWRKS_LE; bridge->dev = pdev;
return serverworks_setup(bridge_dev);
default: pci_set_drvdata(pdev, bridge);
if(agp_try_unsupported) { return agp_add_bridge(bridge);
agp_bridge->type = SVWRKS_GENERIC;
return serverworks_setup(bridge_dev);
}
break;
}
return -ENODEV;
} }
static struct agp_driver serverworks_agp_driver = { static void __devexit agp_serverworks_remove(struct pci_dev *pdev)
.owner = THIS_MODULE,
};
static int __init agp_serverworks_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{ {
if (agp_find_supported_device(dev) == 0) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
serverworks_agp_driver.dev = dev;
agp_register_driver(&serverworks_agp_driver); agp_remove_bridge(bridge);
return 0; agp_put_bridge(bridge);
}
return -ENODEV;
} }
static struct pci_device_id agp_serverworks_pci_table[] __initdata = { static struct pci_device_id agp_serverworks_pci_table[] __initdata = {
...@@ -557,22 +536,16 @@ static struct __initdata pci_driver agp_serverworks_pci_driver = { ...@@ -557,22 +536,16 @@ static struct __initdata pci_driver agp_serverworks_pci_driver = {
.name = "agpgart-serverworks", .name = "agpgart-serverworks",
.id_table = agp_serverworks_pci_table, .id_table = agp_serverworks_pci_table,
.probe = agp_serverworks_probe, .probe = agp_serverworks_probe,
.remove = agp_serverworks_remove,
}; };
static int __init agp_serverworks_init(void) static int __init agp_serverworks_init(void)
{ {
int ret_val; return pci_module_init(&agp_serverworks_pci_driver);
ret_val = pci_module_init(&agp_serverworks_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_serverworks_cleanup(void) static void __exit agp_serverworks_cleanup(void)
{ {
agp_unregister_driver(&serverworks_agp_driver);
pci_unregister_driver(&agp_serverworks_pci_driver); pci_unregister_driver(&agp_serverworks_pci_driver);
} }
......
...@@ -18,9 +18,9 @@ static int via_fetch_size(void) ...@@ -18,9 +18,9 @@ static int via_fetch_size(void)
u8 temp; u8 temp;
struct aper_size_info_8 *values; struct aper_size_info_8 *values;
values = A_SIZE_8(agp_bridge->aperture_sizes); values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp); pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -79,7 +79,7 @@ static unsigned long via_mask_memory(unsigned long addr, int type) ...@@ -79,7 +79,7 @@ static unsigned long via_mask_memory(unsigned long addr, int type)
{ {
/* Memory type is ignored */ /* Memory type is ignored */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
...@@ -107,11 +107,11 @@ static int via_fetch_size_agp3(void) ...@@ -107,11 +107,11 @@ static int via_fetch_size_agp3(void)
u16 temp; u16 temp;
struct aper_size_info_16 *values; struct aper_size_info_16 *values;
values = A_SIZE_16(agp_bridge->aperture_sizes); values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp); pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp);
temp &= 0xfff; temp &= 0xfff;
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -174,99 +174,55 @@ static struct aper_size_info_16 via_generic_agp3_sizes[11] = ...@@ -174,99 +174,55 @@ static struct aper_size_info_16 via_generic_agp3_sizes[11] =
{ 2048, 524288, 9, 1<<11} /* 2GB <- Max supported */ { 2048, 524288, 9, 1<<11} /* 2GB <- Max supported */
}; };
struct agp_bridge_driver via_agp3_driver = {
.owner = THIS_MODULE,
.masks = via_generic_masks,
.aperture_sizes = via_generic_agp3_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 10,
.configure = via_configure_agp3,
.fetch_size = via_fetch_size_agp3,
.cleanup = via_cleanup_agp3,
.tlb_flush = via_tlbflush_agp3,
.mask_memory = via_mask_memory,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.suspend = agp_generic_suspend,
.resume = agp_generic_resume,
};
static int __init via_generic_agp3_setup (struct pci_dev *pdev) struct agp_bridge_driver via_driver = {
{ .owner = THIS_MODULE,
agp_bridge->dev = pdev; .masks = via_generic_masks,
agp_bridge->type = VIA_GENERIC; .aperture_sizes = via_generic_sizes,
agp_bridge->masks = via_generic_masks; .size_type = U8_APER_SIZE,
agp_bridge->aperture_sizes = (void *) via_generic_agp3_sizes; .num_aperture_sizes = 7,
agp_bridge->size_type = U16_APER_SIZE; .configure = via_configure,
agp_bridge->num_aperture_sizes = 10; .fetch_size = via_fetch_size,
agp_bridge->dev_private_data = NULL; .cleanup = via_cleanup,
agp_bridge->needs_scratch_page = FALSE; .tlb_flush = via_tlbflush,
agp_bridge->agp_enable = agp_generic_enable; .mask_memory = via_mask_memory,
agp_bridge->configure = via_configure_agp3; .agp_enable = agp_generic_enable,
agp_bridge->fetch_size = via_fetch_size_agp3; .cache_flush = global_cache_flush,
agp_bridge->cleanup = via_cleanup_agp3; .create_gatt_table = agp_generic_create_gatt_table,
agp_bridge->tlb_flush = via_tlbflush_agp3; .free_gatt_table = agp_generic_free_gatt_table,
agp_bridge->mask_memory = via_mask_memory; .insert_memory = agp_generic_insert_memory,
agp_bridge->cache_flush = global_cache_flush; .remove_memory = agp_generic_remove_memory,
agp_bridge->create_gatt_table = agp_generic_create_gatt_table; .alloc_by_type = agp_generic_alloc_by_type,
agp_bridge->free_gatt_table = agp_generic_free_gatt_table; .free_by_type = agp_generic_free_by_type,
agp_bridge->insert_memory = agp_generic_insert_memory; .agp_alloc_page = agp_generic_alloc_page,
agp_bridge->remove_memory = agp_generic_remove_memory; .agp_destroy_page = agp_generic_destroy_page,
agp_bridge->alloc_by_type = agp_generic_alloc_by_type; .suspend = agp_generic_suspend,
agp_bridge->free_by_type = agp_generic_free_by_type; .resume = agp_generic_resume,
agp_bridge->agp_alloc_page = agp_generic_alloc_page; };
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->suspend = agp_generic_suspend;
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
static int __init via_generic_setup (struct pci_dev *pdev)
{
/* Garg, there are KT400s with KT266 IDs. */
if (pdev->device == PCI_DEVICE_ID_VIA_8367_0) {
/* Is there a KT400 subsystem ? */
if (pdev->subsystem_device==PCI_DEVICE_ID_VIA_8377_0) {
u8 reg;
printk (KERN_INFO PFX "Found KT400 in disguise as a KT266.\n");
/* Check AGP compatibility mode. */
pci_read_config_byte(pdev, VIA_AGPSEL, &reg);
if ((reg & (1<<1))==0)
return via_generic_agp3_setup(pdev);
/* Its in 2.0 mode, drop through. */
}
}
agp_bridge->masks = via_generic_masks;
agp_bridge->aperture_sizes = (void *) via_generic_sizes;
agp_bridge->size_type = U8_APER_SIZE;
agp_bridge->num_aperture_sizes = 7;
agp_bridge->dev_private_data = NULL;
agp_bridge->needs_scratch_page = FALSE;
agp_bridge->configure = via_configure;
agp_bridge->fetch_size = via_fetch_size;
agp_bridge->cleanup = via_cleanup;
agp_bridge->tlb_flush = via_tlbflush;
agp_bridge->mask_memory = via_mask_memory;
agp_bridge->agp_enable = agp_generic_enable;
agp_bridge->cache_flush = global_cache_flush;
agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
agp_bridge->insert_memory = agp_generic_insert_memory;
agp_bridge->remove_memory = agp_generic_remove_memory;
agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
agp_bridge->free_by_type = agp_generic_free_by_type;
agp_bridge->agp_alloc_page = agp_generic_alloc_page;
agp_bridge->agp_destroy_page = agp_generic_destroy_page;
agp_bridge->suspend = agp_generic_suspend;
agp_bridge->resume = agp_generic_resume;
agp_bridge->cant_use_aperture = 0;
return 0;
}
/* The KT400 does magick to put the AGP bridge compliant with the same
* standards version as the graphics card. */
static int __init via_kt400_setup(struct pci_dev *pdev)
{
u8 reg;
pci_read_config_byte(pdev, VIA_AGPSEL, &reg);
/* Check AGP 2.0 compatibility mode. */
if ((reg & (1<<1))==0)
return via_generic_agp3_setup(pdev);
return via_generic_setup(pdev);
}
static struct agp_device_ids via_agp_device_ids[] __initdata = static struct agp_device_ids via_agp_device_ids[] __initdata =
{ {
...@@ -310,7 +266,7 @@ static struct agp_device_ids via_agp_device_ids[] __initdata = ...@@ -310,7 +266,7 @@ static struct agp_device_ids via_agp_device_ids[] __initdata =
/* VT8361 */ /* VT8361 */
{ {
.device_id = PCI_DEVICE_ID_VIA_8361, // 0x3112 .device_id = PCI_DEVICE_ID_VIA_8361,
.chipset_name = "Apollo KLE133", .chipset_name = "Apollo KLE133",
}, },
...@@ -353,7 +309,6 @@ static struct agp_device_ids via_agp_device_ids[] __initdata = ...@@ -353,7 +309,6 @@ static struct agp_device_ids via_agp_device_ids[] __initdata =
{ {
.device_id = PCI_DEVICE_ID_VIA_8377_0, .device_id = PCI_DEVICE_ID_VIA_8377_0,
.chipset_name = "Apollo Pro KT400", .chipset_name = "Apollo Pro KT400",
.chipset_setup = via_kt400_setup,
}, },
/* VT8604 / VT8605 / VT8603 / TwisterT /* VT8604 / VT8605 / VT8603 / TwisterT
...@@ -402,74 +357,99 @@ static struct agp_device_ids via_agp_device_ids[] __initdata = ...@@ -402,74 +357,99 @@ static struct agp_device_ids via_agp_device_ids[] __initdata =
/* P4M400 */ /* P4M400 */
{ {
.device_id = PCI_DEVICE_ID_VIA_P4M400, .device_id = PCI_DEVICE_ID_VIA_P4M400,
.chipset_name = "PM400", .chipset_name = "P4M400",
}, },
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
static int __init agp_via_probe(struct pci_dev *pdev,
/* scan table above for supported devices */ const struct pci_device_id *ent)
static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
{ {
int j=0; struct agp_device_ids *devs = via_agp_device_ids;
struct agp_device_ids *devs; struct agp_bridge_data *bridge;
int j = 0;
devs = via_agp_device_ids; u8 cap_ptr, reg;
while (devs[j].chipset_name != NULL) { cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (pdev->device == devs[j].device_id) { if (!cap_ptr)
printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name); return -ENODEV;
agp_bridge->type = VIA_GENERIC;
if (devs[j].chipset_setup != NULL) /* probe for known chipsets */
return devs[j].chipset_setup(pdev); for (j = 0; devs[j].chipset_name; j++) {
else if (pdev->device == devs[j].device_id) {
return via_generic_setup(pdev); printk (KERN_INFO PFX "Detected VIA %s chipset\n",
devs[j].chipset_name);
goto found;
} }
j++;
} }
/* try init anyway, if user requests it */
if (agp_try_unsupported) { if (agp_try_unsupported) {
printk(KERN_WARNING PFX "Trying generic VIA routines" printk(KERN_ERR PFX
" for device id: %04x\n", pdev->device); "Unsupported VIA chipset (device id: %04x),"
agp_bridge->type = VIA_GENERIC; " you might want to try agp_try_unsupported=1.\n",
return via_generic_setup(pdev); pdev->device);
return -ENODEV;
} }
printk(KERN_ERR PFX "Unsupported VIA chipset (device id: %04x)," printk(KERN_WARNING PFX "Trying generic VIA routines"
" you might want to try agp_try_unsupported=1.\n", pdev->device); " for device id: %04x\n", pdev->device);
return -ENODEV;
}
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
static struct agp_driver via_agp_driver = { bridge->dev = pdev;
.owner = THIS_MODULE, bridge->capndx = cap_ptr;
};
switch (pdev->device) {
case PCI_DEVICE_ID_VIA_8367_0:
/*
* Garg, there are KT400s with KT266 IDs.
*/
/* Is there a KT400 subsystem ? */
if (pdev->subsystem_device != PCI_DEVICE_ID_VIA_8377_0)
break;
printk(KERN_INFO PFX "Found KT400 in disguise as a KT266.\n");
/*FALLTHROUGH*/
case PCI_DEVICE_ID_VIA_8377_0:
/*
* The KT400 does magick to put the AGP bridge compliant
* with the same standards version as the graphics card.
*/
pci_read_config_byte(pdev, VIA_AGPSEL, &reg);
/* Check AGP 2.0 compatibility mode. */
if ((reg & (1<<1))==0) {
bridge->driver = &via_agp3_driver;
break;
}
/*FALLTHROUGH*/
default:
bridge->driver = &via_driver;
break;
}
static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
u8 cap_ptr = 0;
cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); bridge->dev = pdev;
if (cap_ptr == 0) bridge->capndx = cap_ptr;
return -ENODEV;
/* probe for known chipsets */ /* Fill in the mode register */
if (agp_lookup_host_bridge (dev) != -ENODEV) { pci_read_config_dword(pdev,
agp_bridge->dev = dev; bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
agp_bridge->capndx = cap_ptr;
/* Fill in the mode register */ pci_set_drvdata(pdev, bridge);
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode); return agp_add_bridge(bridge);
via_agp_driver.dev = dev;
agp_register_driver(&via_agp_driver);
return 0;
}
return -ENODEV;
} }
static void __devexit agp_via_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_via_pci_table[] __initdata = { static struct pci_device_id agp_via_pci_table[] __initdata = {
{ {
...@@ -490,28 +470,20 @@ static struct __initdata pci_driver agp_via_pci_driver = { ...@@ -490,28 +470,20 @@ static struct __initdata pci_driver agp_via_pci_driver = {
.name = "agpgart-via", .name = "agpgart-via",
.id_table = agp_via_pci_table, .id_table = agp_via_pci_table,
.probe = agp_via_probe, .probe = agp_via_probe,
.remove = agp_via_remove,
}; };
static int __init agp_via_init(void) static int __init agp_via_init(void)
{ {
int ret_val; return pci_module_init(&agp_via_pci_driver);
ret_val = pci_module_init(&agp_via_pci_driver);
if (ret_val)
agp_bridge->type = NOT_SUPPORTED;
return ret_val;
} }
static void __exit agp_via_cleanup(void) static void __exit agp_via_cleanup(void)
{ {
agp_unregister_driver(&via_agp_driver);
pci_unregister_driver(&agp_via_pci_driver); pci_unregister_driver(&agp_via_pci_driver);
} }
module_init(agp_via_init); module_init(agp_via_init);
module_exit(agp_via_cleanup); module_exit(agp_via_cleanup);
......
/* /*
* AGPGART module version 0.99 * AGPGART module version 0.100
* Copyright (C) 2002-2003 Dave Jones
* Copyright (C) 1999 Jeff Hartmann * Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc. * Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc. * Copyright (C) 1999 Xi Graphics, Inc.
...@@ -37,45 +38,7 @@ ...@@ -37,45 +38,7 @@
enum chipset_type { enum chipset_type {
NOT_SUPPORTED, NOT_SUPPORTED,
INTEL_GENERIC, SUPPORTED,
INTEL_LX,
INTEL_BX,
INTEL_GX,
INTEL_I810,
INTEL_I815,
INTEL_I820,
INTEL_I830_M,
INTEL_I845_G,
INTEL_I855_PM,
INTEL_I865_G,
INTEL_I840,
INTEL_I845,
INTEL_I850,
INTEL_I860,
INTEL_460GX,
INTEL_E7505,
VIA_GENERIC,
SIS_GENERIC,
AMD_GENERIC,
AMD_IRONGATE,
AMD_761,
AMD_762,
AMD_8151,
ALI_M1541,
ALI_M1621,
ALI_M1631,
ALI_M1632,
ALI_M1641,
ALI_M1644,
ALI_M1647,
ALI_M1651,
ALI_M1671,
ALI_GENERIC,
SVWRKS_HE,
SVWRKS_LE,
SVWRKS_GENERIC,
HP_ZX1,
ALPHA_CORE_AGP,
}; };
struct agp_version { struct agp_version {
...@@ -98,16 +61,11 @@ typedef struct _agp_kern_info { ...@@ -98,16 +61,11 @@ typedef struct _agp_kern_info {
} agp_kern_info; } agp_kern_info;
/* /*
* The agp_memory structure has information * The agp_memory structure has information about the block of agp memory
* about the block of agp memory allocated. * allocated. A caller may manipulate the next and prev pointers to link
* A caller may manipulate the next and prev * each allocated item into a list. These pointers are ignored by the backend.
* pointers to link each allocated item into * Everything else should never be written to, but the caller may read any of
* a list. These pointers are ignored by the * the items to detrimine the status of this block of agp memory.
* backend. Everything else should never be
* written to, but the caller may read any of
* the items to detrimine the status of this
* block of agp memory.
*
*/ */
typedef struct _agp_memory { typedef struct _agp_memory {
...@@ -127,126 +85,19 @@ typedef struct _agp_memory { ...@@ -127,126 +85,19 @@ typedef struct _agp_memory {
#define AGP_NORMAL_MEMORY 0 #define AGP_NORMAL_MEMORY 0
extern void agp_free_memory(agp_memory *); extern void agp_free_memory(agp_memory *);
/*
* agp_free_memory :
*
* This function frees memory associated with
* an agp_memory pointer. It is the only function
* that can be called when the backend is not owned
* by the caller. (So it can free memory on client
* death.)
*
* It takes an agp_memory pointer as an argument.
*
*/
extern agp_memory *agp_allocate_memory(size_t, u32); extern agp_memory *agp_allocate_memory(size_t, u32);
/*
* agp_allocate_memory :
*
* This function allocates a group of pages of
* a certain type.
*
* It takes a size_t argument of the number of pages, and
* an u32 argument of the type of memory to be allocated.
* Every agp bridge device will allow you to allocate
* AGP_NORMAL_MEMORY which maps to physical ram. Any other
* type is device dependent.
*
* It returns NULL whenever memory is unavailable.
*
*/
extern int agp_copy_info(agp_kern_info *); extern int agp_copy_info(agp_kern_info *);
/*
* agp_copy_info :
*
* This function copies information about the
* agp bridge device and the state of the agp
* backend into an agp_kern_info pointer.
*
* It takes an agp_kern_info pointer as an
* argument. The caller should insure that
* this pointer is valid.
*
*/
extern int agp_bind_memory(agp_memory *, off_t); extern int agp_bind_memory(agp_memory *, off_t);
/*
* agp_bind_memory :
*
* This function binds an agp_memory structure
* into the graphics aperture translation table.
*
* It takes an agp_memory pointer and an offset into
* the graphics aperture translation table as arguments
*
* It returns -EINVAL if the pointer == NULL.
* It returns -EBUSY if the area of the table
* requested is already in use.
*
*/
extern int agp_unbind_memory(agp_memory *); extern int agp_unbind_memory(agp_memory *);
/*
* agp_unbind_memory :
*
* This function removes an agp_memory structure
* from the graphics aperture translation table.
*
* It takes an agp_memory pointer as an argument.
*
* It returns -EINVAL if this piece of agp_memory
* is not currently bound to the graphics aperture
* translation table or if the agp_memory
* pointer == NULL
*
*/
extern void agp_enable(u32); extern void agp_enable(u32);
/*
* agp_enable :
*
* This function initializes the agp point-to-point
* connection.
*
* It takes an agp mode register as an argument
*
*/
extern int agp_backend_acquire(void); extern int agp_backend_acquire(void);
/*
* agp_backend_acquire :
*
* This Function attempts to acquire the agp
* backend.
*
* returns -EBUSY if agp is in use,
* returns 0 if the caller owns the agp backend
*/
extern void agp_backend_release(void); extern void agp_backend_release(void);
/* /*
* agp_backend_release : * Interface between drm and agp code. When agp initializes, it makes
* * the below structure available via inter_module_register(), drm might
* This Function releases the lock on the agp * use it. Keith Owens <kaos@ocs.com.au> 28 Oct 2000.
* backend.
*
* The caller must insure that the graphics
* aperture translation table is read for use
* by another entity. (Ensure that all memory
* it bound is unbound.)
*
*/ */
typedef struct { typedef struct {
void (*free_memory)(agp_memory *); void (*free_memory)(agp_memory *);
agp_memory *(*allocate_memory)(size_t, u32); agp_memory *(*allocate_memory)(size_t, u32);
...@@ -260,10 +111,4 @@ typedef struct { ...@@ -260,10 +111,4 @@ typedef struct {
extern const drm_agp_t *drm_agp_p; extern const drm_agp_t *drm_agp_p;
/*
* Interface between drm and agp code. When agp initializes, it makes
* the above structure available via inter_module_register(), drm might
* use it. Keith Owens <kaos@ocs.com.au> 28 Oct 2000.
*/
#endif /* _AGP_BACKEND_H */ #endif /* _AGP_BACKEND_H */
...@@ -27,17 +27,19 @@ ...@@ -27,17 +27,19 @@
#ifndef _AGP_H #ifndef _AGP_H
#define _AGP_H 1 #define _AGP_H 1
#include <linux/agp_backend.h>
#define AGPIOC_BASE 'A' #define AGPIOC_BASE 'A'
#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, agp_info*) #define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, struct agp_info*)
#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1) #define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1)
#define AGPIOC_RELEASE _IO (AGPIOC_BASE, 2) #define AGPIOC_RELEASE _IO (AGPIOC_BASE, 2)
#define AGPIOC_SETUP _IOW (AGPIOC_BASE, 3, agp_setup*) #define AGPIOC_SETUP _IOW (AGPIOC_BASE, 3, struct agp_setup*)
#define AGPIOC_RESERVE _IOW (AGPIOC_BASE, 4, agp_region*) #define AGPIOC_RESERVE _IOW (AGPIOC_BASE, 4, struct agp_region*)
#define AGPIOC_PROTECT _IOW (AGPIOC_BASE, 5, agp_region*) #define AGPIOC_PROTECT _IOW (AGPIOC_BASE, 5, struct agp_region*)
#define AGPIOC_ALLOCATE _IOWR(AGPIOC_BASE, 6, agp_allocate*) #define AGPIOC_ALLOCATE _IOWR(AGPIOC_BASE, 6, struct agp_allocate*)
#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int) #define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, agp_bind*) #define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, struct agp_bind*)
#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, agp_unbind*) #define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, struct agp_unbind*)
#define AGP_DEVICE "/dev/agpgart" #define AGP_DEVICE "/dev/agpgart"
...@@ -112,19 +114,7 @@ typedef struct _agp_unbind { ...@@ -112,19 +114,7 @@ typedef struct _agp_unbind {
#define AGPGART_MINOR 175 #define AGPGART_MINOR 175
#define AGP_UNLOCK() up(&(agp_fe.agp_mutex)); struct agp_info {
#define AGP_LOCK() down(&(agp_fe.agp_mutex));
#define AGP_LOCK_INIT() sema_init(&(agp_fe.agp_mutex), 1)
#ifndef _AGP_BACKEND_H
struct _agp_version {
u16 major;
u16 minor;
} agp_version;
#endif
typedef struct _agp_info {
struct agp_version version; /* version of the driver */ struct agp_version version; /* version of the driver */
u32 bridge_id; /* bridge vendor/device */ u32 bridge_id; /* bridge vendor/device */
u32 agp_mode; /* mode info of bridge */ u32 agp_mode; /* mode info of bridge */
...@@ -133,34 +123,34 @@ typedef struct _agp_info { ...@@ -133,34 +123,34 @@ typedef struct _agp_info {
size_t pg_total; /* max pages (swap + system) */ size_t pg_total; /* max pages (swap + system) */
size_t pg_system; /* max pages (system) */ size_t pg_system; /* max pages (system) */
size_t pg_used; /* current pages used */ size_t pg_used; /* current pages used */
} agp_info; };
typedef struct _agp_setup { struct agp_setup {
u32 agp_mode; /* mode info of bridge */ u32 agp_mode; /* mode info of bridge */
} agp_setup; };
/* /*
* The "prot" down below needs still a "sleep" flag somehow ... * The "prot" down below needs still a "sleep" flag somehow ...
*/ */
typedef struct _agp_segment { struct agp_segment {
off_t pg_start; /* starting page to populate */ off_t pg_start; /* starting page to populate */
size_t pg_count; /* number of pages */ size_t pg_count; /* number of pages */
int prot; /* prot flags for mmap */ int prot; /* prot flags for mmap */
} agp_segment; };
typedef struct _agp_segment_priv { struct agp_segment_priv {
off_t pg_start; off_t pg_start;
size_t pg_count; size_t pg_count;
pgprot_t prot; pgprot_t prot;
} agp_segment_priv; };
typedef struct _agp_region { struct agp_region {
pid_t pid; /* pid of process */ pid_t pid; /* pid of process */
size_t seg_count; /* number of segments */ size_t seg_count; /* number of segments */
struct _agp_segment *seg_list; struct agp_segment *seg_list;
} agp_region; };
typedef struct _agp_allocate { struct agp_allocate {
int key; /* tag of allocation */ int key; /* tag of allocation */
size_t pg_count; /* number of pages */ size_t pg_count; /* number of pages */
u32 type; /* 0 == normal, other devspec */ u32 type; /* 0 == normal, other devspec */
...@@ -168,34 +158,34 @@ typedef struct _agp_allocate { ...@@ -168,34 +158,34 @@ typedef struct _agp_allocate {
* need a phys address of the * need a phys address of the
* actual page behind the gatt * actual page behind the gatt
* table) */ * table) */
} agp_allocate; };
typedef struct _agp_bind { struct agp_bind {
int key; /* tag of allocation */ int key; /* tag of allocation */
off_t pg_start; /* starting page to populate */ off_t pg_start; /* starting page to populate */
} agp_bind; };
typedef struct _agp_unbind { struct agp_unbind {
int key; /* tag of allocation */ int key; /* tag of allocation */
u32 priority; /* priority for paging out */ u32 priority; /* priority for paging out */
} agp_unbind; };
typedef struct _agp_client { struct agp_client {
struct _agp_client *next; struct agp_client *next;
struct _agp_client *prev; struct agp_client *prev;
pid_t pid; pid_t pid;
int num_segments; int num_segments;
agp_segment_priv **segments; struct agp_segment_priv **segments;
} agp_client; };
typedef struct _agp_controller { struct agp_controller {
struct _agp_controller *next; struct agp_controller *next;
struct _agp_controller *prev; struct agp_controller *prev;
pid_t pid; pid_t pid;
int num_clients; int num_clients;
agp_memory *pool; agp_memory *pool;
agp_client *clients; struct agp_client *clients;
} agp_controller; };
#define AGP_FF_ALLOW_CLIENT 0 #define AGP_FF_ALLOW_CLIENT 0
#define AGP_FF_ALLOW_CONTROLLER 1 #define AGP_FF_ALLOW_CONTROLLER 1
...@@ -203,18 +193,18 @@ typedef struct _agp_controller { ...@@ -203,18 +193,18 @@ typedef struct _agp_controller {
#define AGP_FF_IS_CONTROLLER 3 #define AGP_FF_IS_CONTROLLER 3
#define AGP_FF_IS_VALID 4 #define AGP_FF_IS_VALID 4
typedef struct _agp_file_private { struct agp_file_private {
struct _agp_file_private *next; struct agp_file_private *next;
struct _agp_file_private *prev; struct agp_file_private *prev;
pid_t my_pid; pid_t my_pid;
long access_flags; /* long req'd for set_bit --RR */ long access_flags; /* long req'd for set_bit --RR */
} agp_file_private; };
struct agp_front_data { struct agp_front_data {
struct semaphore agp_mutex; struct semaphore agp_mutex;
agp_controller *current_controller; struct agp_controller *current_controller;
agp_controller *controllers; struct agp_controller *controllers;
agp_file_private *file_priv_list; struct agp_file_private *file_priv_list;
u8 used_by_controller; u8 used_by_controller;
u8 backend_acquired; u8 backend_acquired;
}; };
......
...@@ -1007,7 +1007,9 @@ ...@@ -1007,7 +1007,9 @@
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL 0x017B #define PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL 0x017B
#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL 0x017C #define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL 0x017C
#define PCI_DEVICE_ID_NVIDIA_IGEFORCE2 0x01a0 #define PCI_DEVICE_ID_NVIDIA_IGEFORCE2 0x01a0
#define PCI_DEVICE_ID_NVIDIA_NFORCE 0x01a4
#define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc
#define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201
#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202
...@@ -1902,10 +1904,13 @@ ...@@ -1902,10 +1904,13 @@
#define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562 #define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562
#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570 #define PCI_DEVICE_ID_INTEL_82865_HB 0x2570
#define PCI_DEVICE_ID_INTEL_82865_IG 0x2572 #define PCI_DEVICE_ID_INTEL_82865_IG 0x2572
#define PCI_DEVICE_ID_INTEL_82875_HB 0x2578
#define PCI_DEVICE_ID_INTEL_82875_IG 0x257b
#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
#define PCI_DEVICE_ID_INTEL_82855_HB 0x3580 #define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
#define PCI_DEVICE_ID_INTEL_82855_IG 0x3582 #define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582
#define PCI_DEVICE_ID_INTEL_80310 0x530d #define PCI_DEVICE_ID_INTEL_80310 0x530d
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment