Commit 614c332e authored by Dave Jones's avatar Dave Jones

Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/bk-linus

into tetrachloride.(none):/mnt/raid/src/kernel/2.5/agpgart
parents eb0a5728 69aeb8fc
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 */
This diff is collapsed.
...@@ -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);
This diff is collapsed.
...@@ -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:
......
This diff is collapsed.
...@@ -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);
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -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);
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -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,11 @@ ...@@ -1902,10 +1904,11 @@
#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_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