Commit 96c37294 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[AGPGART] proper agp_bridge_driver.

Christoph with the goods once more...
>Okay, this does the converion for all drivers, it's ontop of my
>previous patches.  enum chipset_type has shrunk to NOT_SUPPORTED
>and SUPPORTED, but I'd like to postpone killing it entirely
>or replacing it by a bool - drm pokes into this and we need to  
>redo the agpgart <-> drm interface for support of multiple garts
>anyway.
parent a04791e7
...@@ -83,14 +83,41 @@ struct aper_size_info_fixed { ...@@ -83,14 +83,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;
...@@ -99,38 +126,12 @@ struct agp_bridge_data { ...@@ -99,38 +126,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))
...@@ -152,9 +153,9 @@ struct agp_bridge_data { ...@@ -152,9 +153,9 @@ struct agp_bridge_data {
#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(bridge) (A_SIZE_8((bridge)->aperture_sizes) + i) #define A_IDX8(bridge) (A_SIZE_8((bridge)->driver->aperture_sizes) + i)
#define A_IDX16(bridge) (A_SIZE_16((bridge)->aperture_sizes) + i) #define A_IDX16(bridge) (A_SIZE_16((bridge)->driver->aperture_sizes) + i)
#define A_IDX32(bridge) (A_SIZE_32((bridge)->aperture_sizes) + i) #define A_IDX32(bridge) (A_SIZE_32((bridge)->driver->aperture_sizes) + i)
#define MAXKEY (4096 * 32) #define MAXKEY (4096 * 32)
#define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page) #define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page)
...@@ -353,20 +354,16 @@ struct agp_device_ids { ...@@ -353,20 +354,16 @@ 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. */ /* Frontend routines. */
int agp_frontend_initialize(void); int agp_frontend_initialize(void);
void agp_frontend_cleanup(void); void agp_frontend_cleanup(void);
/* Backend routines. */
int agp_register_driver (struct agp_driver *drv);
int agp_unregister_driver(struct agp_driver *drv);
/* Generic routines. */ /* Generic routines. */
void agp_generic_enable(u32 mode); void agp_generic_enable(u32 mode);
int agp_generic_create_gatt_table(void); int agp_generic_create_gatt_table(void);
......
...@@ -19,9 +19,9 @@ static int ali_fetch_size(void) ...@@ -19,9 +19,9 @@ static int ali_fetch_size(void)
pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp); pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
temp &= ~(0xfffffff0); temp &= ~(0xfffffff0);
values = A_SIZE_32(agp_bridge->aperture_sizes); values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -118,7 +118,7 @@ static unsigned long ali_mask_memory(unsigned long addr, int type) ...@@ -118,7 +118,7 @@ static unsigned long ali_mask_memory(unsigned long addr, int type)
{ {
/* Memory type is ignored */ /* Memory type is ignored */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static void m1541_cache_flush(void) static void m1541_cache_flush(void)
...@@ -196,10 +196,10 @@ static struct aper_size_info_32 ali_generic_sizes[7] = ...@@ -196,10 +196,10 @@ static struct aper_size_info_32 ali_generic_sizes[7] =
{4, 1024, 0, 3} {4, 1024, 0, 3}
}; };
struct agp_bridge_data ali_generic_bridge = { struct agp_bridge_driver ali_generic_bridge = {
.type = ALI_GENERIC, .owner = THIS_MODULE,
.masks = ali_generic_masks, .masks = ali_generic_masks,
.aperture_sizes = (void *)ali_generic_sizes, .aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE, .size_type = U32_APER_SIZE,
.num_aperture_sizes = 7, .num_aperture_sizes = 7,
.configure = ali_configure, .configure = ali_configure,
...@@ -221,10 +221,10 @@ struct agp_bridge_data ali_generic_bridge = { ...@@ -221,10 +221,10 @@ struct agp_bridge_data ali_generic_bridge = {
.resume = agp_generic_resume, .resume = agp_generic_resume,
}; };
struct agp_bridge_data ali_m1541_bridge = { struct agp_bridge_driver ali_m1541_bridge = {
.type = ALI_GENERIC, .owner = THIS_MODULE,
.masks = ali_generic_masks, .masks = ali_generic_masks,
.aperture_sizes = (void *)ali_generic_sizes, .aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE, .size_type = U32_APER_SIZE,
.num_aperture_sizes = 7, .num_aperture_sizes = 7,
.configure = ali_configure, .configure = ali_configure,
...@@ -288,10 +288,6 @@ struct agp_device_ids ali_agp_device_ids[] __initdata = ...@@ -288,10 +288,6 @@ struct agp_device_ids ali_agp_device_ids[] __initdata =
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
static struct agp_driver ali_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_ali_probe(struct pci_dev *pdev, static int __init agp_ali_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
...@@ -320,13 +316,18 @@ static int __init agp_ali_probe(struct pci_dev *pdev, ...@@ -320,13 +316,18 @@ static int __init agp_ali_probe(struct pci_dev *pdev,
printk(KERN_WARNING PFX "Trying generic ALi routines" printk(KERN_WARNING PFX "Trying generic ALi routines"
" for device id: %04x\n", pdev->device); " for device id: %04x\n", pdev->device);
bridge = &ali_generic_bridge;
goto generic;
found: found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
switch (pdev->device) { switch (pdev->device) {
case PCI_DEVICE_ID_AL_M1541: case PCI_DEVICE_ID_AL_M1541:
bridge = &ali_m1541_bridge; bridge->driver = &ali_m1541_bridge;
break; break;
case PCI_DEVICE_ID_AL_M1621: case PCI_DEVICE_ID_AL_M1621:
pci_read_config_byte(pdev, 0xFB, &hidden_1621_id); pci_read_config_byte(pdev, 0xFB, &hidden_1621_id);
...@@ -351,31 +352,29 @@ static int __init agp_ali_probe(struct pci_dev *pdev, ...@@ -351,31 +352,29 @@ static int __init agp_ali_probe(struct pci_dev *pdev,
default: default:
break; break;
} }
/*FALLTHROUGH*/
default: default:
bridge = &ali_generic_bridge; bridge->driver = &ali_generic_bridge;
} }
printk(KERN_INFO PFX "Detected ALi %s chipset\n", printk(KERN_INFO PFX "Detected ALi %s chipset\n",
devs[j].chipset_name); devs[j].chipset_name);
generic:
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */ /* Fill in the mode register */
pci_read_config_dword(pdev, pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS, bridge->capndx+PCI_AGP_STATUS,
&bridge->mode); &bridge->mode);
memcpy(agp_bridge, bridge, sizeof(struct agp_bridge_data));
ali_agp_driver.dev = pdev; pci_set_drvdata(pdev, bridge);
agp_register_driver(&ali_agp_driver); return agp_add_bridge(bridge);
return 0;
} }
static void __exit agp_ali_remove(struct pci_dev *pdev) static void __exit agp_ali_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&ali_agp_driver); struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_ali_pci_table[] __initdata = { static struct pci_device_id agp_ali_pci_table[] __initdata = {
......
...@@ -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,23 +121,17 @@ static int alpha_core_agp_remove_memory(agp_memory *mem, off_t pg_start, ...@@ -121,23 +121,17 @@ 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,
};
struct agp_bridge_data alpha_core_agp_bridge = {
.type = ALPHA_CORE_AGP,
.masks = alpha_core_agp_masks, .masks = alpha_core_agp_masks,
.aperture_sizes = aper_size, .aperture_sizes = aper_size,
.current_size = aper_size, /* only one entry */ .current_size = aper_size, /* only one entry */
.size_type = FIXED_APER_SIZE, .size_type = FIXED_APER_SIZE,
.num_aperture_sizes = 1, .num_aperture_sizes = 1,
.dev_private_data = agp,
.configure = alpha_core_agp_configure, .configure = alpha_core_agp_configure,
.fetch_size = alpha_core_agp_fetch_size, .fetch_size = alpha_core_agp_fetch_size,
.cleanup = alpha_core_agp_cleanup, .cleanup = alpha_core_agp_cleanup,
...@@ -158,6 +152,8 @@ struct agp_bridge_data alpha_core_agp_bridge = { ...@@ -158,6 +152,8 @@ struct agp_bridge_data alpha_core_agp_bridge = {
.vm_ops = &alpha_core_agp_vm_ops, .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)
{ {
...@@ -190,14 +186,20 @@ alpha_core_agp_setup(void) ...@@ -190,14 +186,20 @@ alpha_core_agp_setup(void)
pdev->device = 0xffff; pdev->device = 0xffff;
pdev->sysdata = agp->hose; pdev->sysdata = agp->hose;
alpha_core_agp_bridge.dev = pdev; alpha_bridge = agp_alloc_bridge();
memcpy(agp_bridge, &alpha_core_agp_bridge, if (!alpha_bridge)
sizeof(struct agp_bridge_data)); goto fail;
alpha_bridge->driver = &alpha_core_agp_driver;
alpha_bridge->dev_private_data = agp;
alpha_bridge->dev = pdev;
alpha_core_agp_driver.dev = pdev;
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)
...@@ -209,8 +211,8 @@ static int __init agp_alpha_core_init(void) ...@@ -209,8 +211,8 @@ static int __init agp_alpha_core_init(void)
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);
......
...@@ -184,8 +184,8 @@ static int amd_irongate_fetch_size(void) ...@@ -184,8 +184,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 +274,7 @@ static unsigned long amd_irongate_mask_memory(unsigned long addr, int type) ...@@ -274,7 +274,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,
...@@ -311,9 +311,9 @@ static int amd_insert_memory(agp_memory * mem, ...@@ -311,9 +311,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;
} }
...@@ -334,7 +334,7 @@ static int amd_remove_memory(agp_memory * mem, off_t pg_start, ...@@ -334,7 +334,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;
} }
...@@ -354,13 +354,12 @@ static struct gatt_mask amd_irongate_masks[] = ...@@ -354,13 +354,12 @@ static struct gatt_mask amd_irongate_masks[] =
{.mask = 0x00000001, .type = 0} {.mask = 0x00000001, .type = 0}
}; };
struct agp_bridge_data amd_irongate_bridge = { struct agp_bridge_driver amd_irongate_driver = {
.type = AMD_GENERIC, .owner = THIS_MODULE,
.masks = amd_irongate_masks, .masks = amd_irongate_masks,
.aperture_sizes = (void *)amd_irongate_sizes, .aperture_sizes = amd_irongate_sizes,
.size_type = LVL2_APER_SIZE, .size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7, .num_aperture_sizes = 7,
.dev_private_data = (void *)&amd_irongate_private,
.configure = amd_irongate_configure, .configure = amd_irongate_configure,
.fetch_size = amd_irongate_fetch_size, .fetch_size = amd_irongate_fetch_size,
.cleanup = amd_irongate_cleanup, .cleanup = amd_irongate_cleanup,
...@@ -397,14 +396,11 @@ struct agp_device_ids amd_agp_device_ids[] __initdata = ...@@ -397,14 +396,11 @@ struct agp_device_ids amd_agp_device_ids[] __initdata =
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
static struct agp_driver amd_k7_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_amdk7_probe(struct pci_dev *pdev, static int __init agp_amdk7_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_device_ids *devs = amd_agp_device_ids; struct agp_device_ids *devs = amd_agp_device_ids;
struct agp_bridge_data *bridge;
u8 cap_ptr; u8 cap_ptr;
int j; int j;
...@@ -416,7 +412,6 @@ static int __init agp_amdk7_probe(struct pci_dev *pdev, ...@@ -416,7 +412,6 @@ static int __init agp_amdk7_probe(struct pci_dev *pdev,
if (pdev->device == devs[j].device_id) { if (pdev->device == devs[j].device_id) {
printk (KERN_INFO PFX "Detected AMD %s chipset\n", printk (KERN_INFO PFX "Detected AMD %s chipset\n",
devs[j].chipset_name); devs[j].chipset_name);
amd_irongate_bridge.type = devs[j].chipset;
goto found; goto found;
} }
} }
...@@ -433,24 +428,30 @@ static int __init agp_amdk7_probe(struct pci_dev *pdev, ...@@ -433,24 +428,30 @@ static int __init agp_amdk7_probe(struct pci_dev *pdev,
" for device id: %04x\n", pdev->device); " for device id: %04x\n", pdev->device);
found: found:
amd_irongate_bridge.dev = pdev; bridge = agp_alloc_bridge();
amd_irongate_bridge.capndx = cap_ptr; if (!bridge)
return -ENOMEM;
bridge->driver = &amd_irongate_driver;
bridge->dev_private_data = &amd_irongate_private,
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */ /* Fill in the mode register */
pci_read_config_dword(pdev, pci_read_config_dword(pdev,
amd_irongate_bridge.capndx+PCI_AGP_STATUS, bridge->capndx+PCI_AGP_STATUS,
&amd_irongate_bridge.mode); &bridge->mode);
memcpy(agp_bridge, &amd_irongate_bridge, sizeof(struct agp_bridge_data)); pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
amd_k7_agp_driver.dev = pdev;
agp_register_driver(&amd_k7_agp_driver);
return 0;
} }
static void __exit agp_amdk7_remove(struct pci_dev *pdev) static void __exit agp_amdk7_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&amd_k7_agp_driver); struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_amdk7_pci_table[] __initdata = { static struct pci_device_id agp_amdk7_pci_table[] __initdata = {
...@@ -489,4 +490,3 @@ module_exit(agp_amdk7_cleanup); ...@@ -489,4 +490,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;
...@@ -61,7 +76,7 @@ static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -61,7 +76,7 @@ static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
} }
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,9 +223,10 @@ static struct gatt_mask amd_8151_masks[] = ...@@ -227,9 +223,10 @@ static struct gatt_mask amd_8151_masks[] =
{.mask = 0x00000001, .type = 0} {.mask = 0x00000001, .type = 0}
}; };
struct agp_bridge_data amd_8151_bridge = { struct agp_bridge_driver amd_8151_driver = {
.owner = THIS_MODULE,
.masks = amd_8151_masks, .masks = amd_8151_masks,
.aperture_sizes = (void *)amd_8151_sizes, .aperture_sizes = amd_8151_sizes,
.size_type = U32_APER_SIZE, .size_type = U32_APER_SIZE,
.num_aperture_sizes = 7, .num_aperture_sizes = 7,
.configure = amd_8151_configure, .configure = amd_8151_configure,
...@@ -251,13 +248,10 @@ struct agp_bridge_data amd_8151_bridge = { ...@@ -251,13 +248,10 @@ struct agp_bridge_data amd_8151_bridge = {
.resume = agp_generic_resume, .resume = agp_generic_resume,
}; };
static struct agp_driver amd_k8_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_amdk8_probe(struct pci_dev *pdev, static int __init agp_amdk8_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_bridge_data *bridge;
struct pci_dev *loop_dev; struct pci_dev *loop_dev;
u8 cap_ptr; u8 cap_ptr;
int i = 0; int i = 0;
...@@ -268,13 +262,18 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev, ...@@ -268,13 +262,18 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
printk(KERN_INFO PFX "Detected Opteron/Athlon64 on-CPU GART\n"); printk(KERN_INFO PFX "Detected Opteron/Athlon64 on-CPU GART\n");
amd_8151_bridge.dev = pdev; bridge = agp_alloc_bridge();
amd_8151_bridge.capndx = cap_ptr; if (!bridge)
return -ENOMEM;
bridge->driver = &amd_8151_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */ /* Fill in the mode register */
pci_read_config_dword(pdev, pci_read_config_dword(pdev,
amd_8151_bridge.capndx+PCI_AGP_STATUS, bridge->capndx+PCI_AGP_STATUS,
&amd_8151_bridge.mode); &bridge->mode);
/* cache pci_devs of northbridges. */ /* cache pci_devs of northbridges. */
pci_for_each_dev(loop_dev) { pci_for_each_dev(loop_dev) {
...@@ -285,20 +284,23 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev, ...@@ -285,20 +284,23 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
hammers[i++] = loop_dev; 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;
} }
} }
memcpy(agp_bridge, &amd_8151_bridge, sizeof(struct agp_bridge_data)); pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
amd_k8_agp_driver.dev = pdev; out_free:
agp_register_driver(&amd_k8_agp_driver); agp_put_bridge(bridge);
return 0; return -ENOMEM;
} }
static void __exit agp_amdk8_remove(struct pci_dev *pdev) static void __exit agp_amdk8_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&amd_k8_agp_driver); struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_amdk8_pci_table[] __initdata = { static struct pci_device_id agp_amdk8_pci_table[] __initdata = {
......
...@@ -130,8 +130,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) ...@@ -130,8 +130,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
bridge->max_memory_agp = agp_find_max(); bridge->max_memory_agp = agp_find_max();
bridge->version = &agp_current_version; bridge->version = &agp_current_version;
if (bridge->needs_scratch_page) { if (bridge->driver->needs_scratch_page) {
void *addr = bridge->agp_alloc_page(); void *addr = bridge->driver->agp_alloc_page();
if (!addr) { 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");
...@@ -140,16 +140,16 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) ...@@ -140,16 +140,16 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
bridge->scratch_page_real = virt_to_phys(addr); bridge->scratch_page_real = virt_to_phys(addr);
bridge->scratch_page = bridge->scratch_page =
bridge->mask_memory(bridge->scratch_page_real, 0); bridge->driver->mask_memory(bridge->scratch_page_real, 0);
} }
size_value = bridge->fetch_size(); 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 (bridge->create_gatt_table()) { if (bridge->driver->create_gatt_table()) {
printk(KERN_ERR PFX printk(KERN_ERR PFX
"unable to get memory for graphics translation table.\n"); "unable to get memory for graphics translation table.\n");
rc = -ENOMEM; rc = -ENOMEM;
...@@ -168,7 +168,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) ...@@ -168,7 +168,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
/* FIXME vmalloc'd memory not guaranteed contiguous */ /* FIXME vmalloc'd memory not guaranteed contiguous */
memset(bridge->key_list, 0, PAGE_SIZE * 4); memset(bridge->key_list, 0, PAGE_SIZE * 4);
if (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;
...@@ -180,10 +180,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) ...@@ -180,10 +180,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
return 0; return 0;
err_out: err_out:
if (bridge->needs_scratch_page) if (bridge->driver->needs_scratch_page)
bridge->agp_destroy_page(phys_to_virt(bridge->scratch_page_real)); bridge->driver->agp_destroy_page(
phys_to_virt(bridge->scratch_page_real));
if (got_gatt) if (got_gatt)
bridge->free_gatt_table(); bridge->driver->free_gatt_table();
if (got_keylist) if (got_keylist)
vfree(bridge->key_list); vfree(bridge->key_list);
return rc; return rc;
...@@ -192,15 +193,16 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) ...@@ -192,15 +193,16 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
/* 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(struct agp_bridge_data *bridge) static void agp_backend_cleanup(struct agp_bridge_data *bridge)
{ {
if (bridge->cleanup) if (bridge->driver->cleanup)
bridge->cleanup(); bridge->driver->cleanup();
if (bridge->free_gatt_table) if (bridge->driver->free_gatt_table)
bridge->free_gatt_table(); bridge->driver->free_gatt_table();
if (bridge->key_list) if (bridge->key_list)
vfree(bridge->key_list); vfree(bridge->key_list);
if (bridge->agp_destroy_page && bridge->needs_scratch_page) if (bridge->driver->agp_destroy_page &&
bridge->agp_destroy_page( bridge->driver->needs_scratch_page)
bridge->driver->agp_destroy_page(
phys_to_virt(bridge->scratch_page_real)); phys_to_virt(bridge->scratch_page_real));
} }
...@@ -208,9 +210,9 @@ static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data) ...@@ -208,9 +210,9 @@ 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;
...@@ -228,66 +230,77 @@ static const drm_agp_t drm_agp = { ...@@ -228,66 +230,77 @@ static const drm_agp_t drm_agp = {
&agp_copy_info &agp_copy_info
}; };
/* 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);
void agp_put_bridge(struct agp_bridge_data *bridge)
{
}
EXPORT_SYMBOL(agp_put_bridge);
int agp_register_driver (struct agp_driver *drv)
int agp_add_bridge(struct agp_bridge_data *bridge)
{ {
int ret_val; 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(agp_bridge); 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_bridge); 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_register_driver); EXPORT_SYMBOL_GPL(agp_add_bridge);
int agp_unregister_driver(struct agp_driver *drv) void agp_remove_bridge(struct agp_bridge_data *bridge)
{ {
if (drv->dev==NULL) bridge->type = NOT_SUPPORTED;
return -ENODEV;
agp_bridge->type = NOT_SUPPORTED;
pm_unregister_all(agp_power); pm_unregister_all(agp_power);
agp_frontend_cleanup(); agp_frontend_cleanup();
agp_backend_cleanup(agp_bridge); 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_unregister_driver); EXPORT_SYMBOL_GPL(agp_remove_bridge);
static int __init agp_init(void) static int __init agp_init(void)
......
...@@ -116,12 +116,12 @@ void agp_free_memory(agp_memory * curr) ...@@ -116,12 +116,12 @@ void agp_free_memory(agp_memory * curr)
agp_unbind_memory(curr); agp_unbind_memory(curr);
if (curr->type != 0) { if (curr->type != 0) {
agp_bridge->free_by_type(curr); agp_bridge->driver->free_by_type(curr);
return; return;
} }
if (curr->page_count != 0) { if (curr->page_count != 0) {
for (i = 0; i < curr->page_count; i++) { for (i = 0; i < curr->page_count; i++) {
agp_bridge->agp_destroy_page(phys_to_virt(curr->memory[i])); agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i]));
} }
} }
agp_free_key(curr->key); agp_free_key(curr->key);
...@@ -156,7 +156,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type) ...@@ -156,7 +156,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return NULL; return NULL;
if (type != 0) { if (type != 0) {
new = agp_bridge->alloc_by_type(page_count, type); new = agp_bridge->driver->alloc_by_type(page_count, type);
return new; return new;
} }
...@@ -168,7 +168,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type) ...@@ -168,7 +168,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return NULL; return NULL;
for (i = 0; i < page_count; i++) { for (i = 0; i < page_count; i++) {
void *addr = agp_bridge->agp_alloc_page(); void *addr = agp_bridge->driver->agp_alloc_page();
if (addr == NULL) { if (addr == NULL) {
agp_free_memory(new); agp_free_memory(new);
...@@ -195,7 +195,7 @@ static int agp_return_size(void) ...@@ -195,7 +195,7 @@ static int agp_return_size(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
current_size = A_SIZE_8(temp)->size; current_size = A_SIZE_8(temp)->size;
break; break;
...@@ -230,7 +230,7 @@ int agp_num_entries(void) ...@@ -230,7 +230,7 @@ int agp_num_entries(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
num_entries = A_SIZE_8(temp)->num_entries; num_entries = A_SIZE_8(temp)->num_entries;
break; break;
...@@ -283,7 +283,7 @@ int agp_copy_info(agp_kern_info * info) ...@@ -283,7 +283,7 @@ int agp_copy_info(agp_kern_info * info)
info->aper_size = agp_return_size(); info->aper_size = agp_return_size();
info->max_memory = agp_bridge->max_memory_agp; info->max_memory = agp_bridge->max_memory_agp;
info->current_memory = atomic_read(&agp_bridge->current_memory_agp); info->current_memory = atomic_read(&agp_bridge->current_memory_agp);
info->cant_use_aperture = agp_bridge->cant_use_aperture; info->cant_use_aperture = agp_bridge->driver->cant_use_aperture;
info->vm_ops = agp_bridge->vm_ops; info->vm_ops = agp_bridge->vm_ops;
info->page_mask = ~0UL; info->page_mask = ~0UL;
return 0; return 0;
...@@ -318,10 +318,10 @@ int agp_bind_memory(agp_memory * curr, off_t pg_start) ...@@ -318,10 +318,10 @@ int agp_bind_memory(agp_memory * curr, off_t pg_start)
return -EINVAL; return -EINVAL;
} }
if (curr->is_flushed == FALSE) { if (curr->is_flushed == FALSE) {
agp_bridge->cache_flush(); agp_bridge->driver->cache_flush();
curr->is_flushed = TRUE; curr->is_flushed = TRUE;
} }
ret_val = agp_bridge->insert_memory(curr, pg_start, curr->type); ret_val = agp_bridge->driver->insert_memory(curr, pg_start, curr->type);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
...@@ -351,7 +351,7 @@ int agp_unbind_memory(agp_memory * curr) ...@@ -351,7 +351,7 @@ int agp_unbind_memory(agp_memory * curr)
if (curr->is_bound != TRUE) if (curr->is_bound != TRUE)
return -EINVAL; return -EINVAL;
ret_val = agp_bridge->remove_memory(curr, curr->pg_start, curr->type); ret_val = agp_bridge->driver->remove_memory(curr, curr->pg_start, curr->type);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
...@@ -494,7 +494,7 @@ int agp_generic_create_gatt_table(void) ...@@ -494,7 +494,7 @@ int agp_generic_create_gatt_table(void)
struct page *page; struct page *page;
/* The generic routines can't handle 2 level gatt's */ /* The generic routines can't handle 2 level gatt's */
if (agp_bridge->size_type == LVL2_APER_SIZE) if (agp_bridge->driver->size_type == LVL2_APER_SIZE)
return -EINVAL; return -EINVAL;
table = NULL; table = NULL;
...@@ -502,9 +502,9 @@ int agp_generic_create_gatt_table(void) ...@@ -502,9 +502,9 @@ int agp_generic_create_gatt_table(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
size = page_order = num_entries = 0; size = page_order = num_entries = 0;
if (agp_bridge->size_type != FIXED_APER_SIZE) { if (agp_bridge->driver->size_type != FIXED_APER_SIZE) {
do { do {
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
size = A_SIZE_8(temp)->size; size = A_SIZE_8(temp)->size;
page_order = page_order =
...@@ -535,7 +535,7 @@ int agp_generic_create_gatt_table(void) ...@@ -535,7 +535,7 @@ int agp_generic_create_gatt_table(void)
if (table == NULL) { if (table == NULL) {
i++; i++;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
agp_bridge->current_size = A_IDX8(agp_bridge); agp_bridge->current_size = A_IDX8(agp_bridge);
break; break;
...@@ -557,7 +557,7 @@ int agp_generic_create_gatt_table(void) ...@@ -557,7 +557,7 @@ int agp_generic_create_gatt_table(void)
} else { } else {
agp_bridge->aperture_size_idx = i; agp_bridge->aperture_size_idx = i;
} }
} while ((table == NULL) && (i < agp_bridge->num_aperture_sizes)); } while (!table && (i < agp_bridge->driver->num_aperture_sizes));
} else { } else {
size = ((struct aper_size_info_fixed *) temp)->size; size = ((struct aper_size_info_fixed *) temp)->size;
page_order = ((struct aper_size_info_fixed *) temp)->page_order; page_order = ((struct aper_size_info_fixed *) temp)->page_order;
...@@ -576,10 +576,10 @@ int agp_generic_create_gatt_table(void) ...@@ -576,10 +576,10 @@ int agp_generic_create_gatt_table(void)
agp_bridge->gatt_table_real = (u32 *) table; agp_bridge->gatt_table_real = (u32 *) table;
agp_gatt_table = (void *)table; agp_gatt_table = (void *)table;
agp_bridge->cache_flush(); agp_bridge->driver->cache_flush();
agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table), agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
(PAGE_SIZE * (1 << page_order))); (PAGE_SIZE * (1 << page_order)));
agp_bridge->cache_flush(); agp_bridge->driver->cache_flush();
if (agp_bridge->gatt_table == NULL) { if (agp_bridge->gatt_table == NULL) {
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
...@@ -623,7 +623,7 @@ int agp_generic_free_gatt_table(void) ...@@ -623,7 +623,7 @@ int agp_generic_free_gatt_table(void)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
page_order = A_SIZE_8(temp)->page_order; page_order = A_SIZE_8(temp)->page_order;
break; break;
...@@ -671,7 +671,7 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -671,7 +671,7 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
temp = agp_bridge->current_size; temp = agp_bridge->current_size;
switch (agp_bridge->size_type) { switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE: case U8_APER_SIZE:
num_entries = A_SIZE_8(temp)->num_entries; num_entries = A_SIZE_8(temp)->num_entries;
break; break;
...@@ -715,15 +715,16 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -715,15 +715,16 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
} }
if (mem->is_flushed == FALSE) { if (mem->is_flushed == FALSE) {
agp_bridge->cache_flush(); agp_bridge->driver->cache_flush();
mem->is_flushed = TRUE; mem->is_flushed = TRUE;
} }
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
agp_bridge->gatt_table[j] = agp_bridge->gatt_table[j] =
agp_bridge->mask_memory(mem->memory[i], mem->type); agp_bridge->driver->mask_memory(
mem->memory[i], mem->type);
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
EXPORT_SYMBOL(agp_generic_insert_memory); EXPORT_SYMBOL(agp_generic_insert_memory);
...@@ -744,7 +745,7 @@ int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type) ...@@ -744,7 +745,7 @@ int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
(unsigned long) agp_bridge->scratch_page; (unsigned long) agp_bridge->scratch_page;
} }
agp_bridge->tlb_flush(mem); agp_bridge->driver->tlb_flush(mem);
return 0; return 0;
} }
EXPORT_SYMBOL(agp_generic_remove_memory); EXPORT_SYMBOL(agp_generic_remove_memory);
...@@ -821,7 +822,7 @@ void agp_enable(u32 mode) ...@@ -821,7 +822,7 @@ void agp_enable(u32 mode)
{ {
if (agp_bridge->type == NOT_SUPPORTED) if (agp_bridge->type == NOT_SUPPORTED)
return; return;
agp_bridge->agp_enable(mode); agp_bridge->driver->agp_enable(mode);
} }
EXPORT_SYMBOL(agp_enable); EXPORT_SYMBOL(agp_enable);
......
...@@ -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,8 +328,8 @@ static unsigned long hp_zx1_mask_memory(unsigned long addr, int type) ...@@ -328,8 +328,8 @@ 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;
} }
struct agp_bridge_data hp_zx1_bridge = { struct agp_bridge_driver hp_zx1_driver = {
.type = HP_ZX1, .owner = THIS_MODULE,
.masks = hp_zx1_masks, .masks = hp_zx1_masks,
.size_type = FIXED_APER_SIZE, .size_type = FIXED_APER_SIZE,
.configure = hp_zx1_configure, .configure = hp_zx1_configure,
...@@ -350,13 +350,10 @@ struct agp_bridge_data hp_zx1_bridge = { ...@@ -350,13 +350,10 @@ struct agp_bridge_data hp_zx1_bridge = {
.cant_use_aperture = 1, .cant_use_aperture = 1,
}; };
static struct agp_driver hp_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_hp_probe(struct pci_dev *pdev, static int __init agp_hp_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_bridge_data *bridge;
int error; int error;
/* ZX1 LBAs can be either PCI or AGP bridges */ /* ZX1 LBAs can be either PCI or AGP bridges */
...@@ -369,18 +366,24 @@ static int __init agp_hp_probe(struct pci_dev *pdev, ...@@ -369,18 +366,24 @@ static int __init agp_hp_probe(struct pci_dev *pdev,
error = hp_zx1_ioc_init(); error = hp_zx1_ioc_init();
if (error) if (error)
return error; return error;
hp_zx1_bridge.dev = pdev;
memcpy(agp_bridge, &hp_zx1_bridge, sizeof(struct agp_bridge_data)); bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
hp_agp_driver.dev = pdev; bridge->driver = &hp_zx1_driver;
agp_register_driver(&hp_agp_driver); bridge->dev = pdev;
return 0;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
} }
static void __exit agp_hp_remove(struct pci_dev *pdev) static void __exit agp_hp_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&hp_agp_driver); struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_hp_pci_table[] __initdata = { static struct pci_device_id agp_hp_pci_table[] __initdata = {
......
...@@ -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);
...@@ -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,13 +519,14 @@ static void i460_destroy_page (void *page) ...@@ -519,13 +519,14 @@ 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));
} }
struct agp_bridge_data intel_i460_bridge = { struct agp_bridge_driver intel_i460_driver = {
.owner = THIS_MODULE,
.masks = i460_masks, .masks = i460_masks,
.aperture_sizes = (void *)i460_sizes, .aperture_sizes = i460_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
.num_aperture_sizes = 3, .num_aperture_sizes = 3,
.configure = i460_configure, .configure = i460_configure,
...@@ -555,32 +556,34 @@ struct agp_bridge_data intel_i460_bridge = { ...@@ -555,32 +556,34 @@ struct agp_bridge_data intel_i460_bridge = {
.cant_use_aperture = 1, .cant_use_aperture = 1,
}; };
static struct agp_driver i460_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_intel_i460_probe(struct pci_dev *pdev, static int __init agp_intel_i460_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_bridge_data *bridge;
u8 cap_ptr; u8 cap_ptr;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr) if (!cap_ptr)
return -ENODEV; return -ENODEV;
intel_i460_bridge.dev = pdev; bridge = agp_alloc_bridge();
intel_i460_bridge.capndx = cap_ptr; if (!bridge)
return -ENOMEM;
memcpy(agp_bridge, &intel_i460_bridge, sizeof(struct agp_bridge_data)); bridge->driver = &intel_i460_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
i460_agp_driver.dev = pdev; pci_set_drvdata(pdev, bridge);
agp_register_driver(&i460_agp_driver); return agp_add_bridge(bridge);
return 0;
} }
static void __exit agp_intel_i460_probe(struct pci_dev *pdev) static void __exit agp_intel_i460_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&i460_agp_driver); 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 = {
......
This diff is collapsed.
...@@ -47,9 +47,9 @@ static int nvidia_fetch_size(void) ...@@ -47,9 +47,9 @@ static int nvidia_fetch_size(void)
pci_read_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE, &size_value); pci_read_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE, &size_value);
size_value &= 0x0f; size_value &= 0x0f;
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 (size_value == values[i].size_value) { if (size_value == 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);
...@@ -143,7 +143,7 @@ static void nvidia_cleanup(void) ...@@ -143,7 +143,7 @@ static void nvidia_cleanup(void)
static unsigned long nvidia_mask_memory(unsigned long addr, int type) static unsigned long nvidia_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;
} }
#if 0 #if 0
...@@ -242,13 +242,12 @@ static struct gatt_mask nvidia_generic_masks[] = ...@@ -242,13 +242,12 @@ static struct gatt_mask nvidia_generic_masks[] =
}; };
struct agp_bridge_data nvidia_bridge = { struct agp_bridge_driver nvidia_driver = {
.type = NVIDIA_GENERIC, .owner = THIS_MODULE,
.masks = nvidia_generic_masks, .masks = nvidia_generic_masks,
.aperture_sizes = (void *) nvidia_generic_sizes, .aperture_sizes = nvidia_generic_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
.num_aperture_sizes = 5, .num_aperture_sizes = 5,
.dev_private_data = (void *) &nvidia_private,
.configure = nvidia_configure, .configure = nvidia_configure,
.fetch_size = nvidia_fetch_size, .fetch_size = nvidia_fetch_size,
.cleanup = nvidia_cleanup, .cleanup = nvidia_cleanup,
...@@ -268,14 +267,10 @@ struct agp_bridge_data nvidia_bridge = { ...@@ -268,14 +267,10 @@ struct agp_bridge_data nvidia_bridge = {
.resume = agp_generic_resume, .resume = agp_generic_resume,
}; };
static struct agp_driver nvidia_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_nvidia_probe(struct pci_dev *pdev, static int __init agp_nvidia_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_bridge_data *bridge;
u8 cap_ptr; u8 cap_ptr;
nvidia_private.dev_1 = nvidia_private.dev_1 =
...@@ -319,24 +314,30 @@ static int __init agp_nvidia_probe(struct pci_dev *pdev, ...@@ -319,24 +314,30 @@ static int __init agp_nvidia_probe(struct pci_dev *pdev,
break; break;
} }
nvidia_bridge.dev = pdev; bridge = agp_alloc_bridge();
nvidia_bridge.capndx = cap_ptr; if (!bridge)
return -ENOMEM;
bridge->driver = &nvidia_driver;
bridge->dev_private_data = &nvidia_private,
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */ /* Fill in the mode register */
pci_read_config_dword(pdev, pci_read_config_dword(pdev,
nvidia_bridge.capndx+PCI_AGP_STATUS, bridge->capndx+PCI_AGP_STATUS,
&nvidia_bridge.mode); &bridge->mode);
memcpy(agp_bridge, &nvidia_bridge, sizeof(struct agp_bridge_data));
nvidia_agp_driver.dev = pdev; pci_set_drvdata(pdev, bridge);
agp_register_driver(&nvidia_agp_driver); return agp_add_bridge(bridge);
return 0;
} }
static void __exit agp_nvidia_remove(struct pci_dev *pdev) static void __exit agp_nvidia_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&nvidia_agp_driver); struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_nvidia_pci_table[] __initdata = { static struct pci_device_id agp_nvidia_pci_table[] __initdata = {
......
...@@ -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,10 +86,10 @@ static struct gatt_mask sis_generic_masks[] = ...@@ -86,10 +86,10 @@ static struct gatt_mask sis_generic_masks[] =
{.mask = 0x00000000, .type = 0} {.mask = 0x00000000, .type = 0}
}; };
struct agp_bridge_data sis_generic_bridge = { struct agp_bridge_driver sis_driver = {
.type = SIS_GENERIC, .owner = THIS_MODULE,
.masks = sis_generic_masks, .masks = sis_generic_masks,
.aperture_sizes = (void *)sis_generic_sizes, .aperture_sizes = sis_generic_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
.num_aperture_sizes = 7, .num_aperture_sizes = 7,
.configure = sis_configure, .configure = sis_configure,
...@@ -168,14 +168,11 @@ struct agp_device_ids sis_agp_device_ids[] __initdata = ...@@ -168,14 +168,11 @@ struct agp_device_ids sis_agp_device_ids[] __initdata =
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
static struct agp_driver sis_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_sis_probe(struct pci_dev *pdev, static int __init agp_sis_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_device_ids *devs = sis_agp_device_ids; struct agp_device_ids *devs = sis_agp_device_ids;
struct agp_bridge_data *bridge;
u8 cap_ptr; u8 cap_ptr;
int j; int j;
...@@ -204,23 +201,29 @@ static int __init agp_sis_probe(struct pci_dev *pdev, ...@@ -204,23 +201,29 @@ static int __init agp_sis_probe(struct pci_dev *pdev,
" for device id: %04x\n", pdev->device); " for device id: %04x\n", pdev->device);
found: found:
sis_generic_bridge.dev = pdev; bridge = agp_alloc_bridge();
sis_generic_bridge.capndx = cap_ptr; if (!bridge)
return -ENOMEM;
bridge->driver = &sis_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */ /* Fill in the mode register */
pci_read_config_dword(pdev, sis_generic_bridge.capndx+PCI_AGP_STATUS, pci_read_config_dword(pdev,
&sis_generic_bridge.mode); bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
memcpy(agp_bridge, &sis_generic_bridge, pci_set_drvdata(pdev, bridge);
sizeof(struct agp_bridge_data)); return agp_add_bridge(bridge);
sis_agp_driver.dev = pdev;
agp_register_driver(&sis_agp_driver);
return 0;
} }
static void __exit agp_sis_remove(struct pci_dev *pdev) static void __exit agp_sis_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&sis_agp_driver); struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_sis_pci_table[] __initdata = { static struct pci_device_id agp_sis_pci_table[] __initdata = {
......
...@@ -203,7 +203,7 @@ static int serverworks_fetch_size(void) ...@@ -203,7 +203,7 @@ static int serverworks_fetch_size(void)
u32 temp2; u32 temp2;
struct aper_size_info_lvl2 *values; struct aper_size_info_lvl2 *values;
values = A_SIZE_LVL2(agp_bridge->aperture_sizes); values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp); pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp);
pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs, pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,
SVWRKS_SIZE_MASK); SVWRKS_SIZE_MASK);
...@@ -211,7 +211,7 @@ static int serverworks_fetch_size(void) ...@@ -211,7 +211,7 @@ static int serverworks_fetch_size(void)
pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp); pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp);
temp2 &= SVWRKS_SIZE_MASK; temp2 &= SVWRKS_SIZE_MASK;
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp2 == values[i].size_value) { if (temp2 == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -224,6 +224,37 @@ static int serverworks_fetch_size(void) ...@@ -224,6 +224,37 @@ static int serverworks_fetch_size(void)
return 0; return 0;
} }
/*
* This routine could be implemented by taking the addresses
* written to the GATT, and flushing them individually. However
* currently it just flushes the whole table. Which is probably
* more efficent, since agp_memory blocks can be a large number of
* entries.
*/
static void serverworks_tlbflush(agp_memory * temp)
{
unsigned long end;
OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 0x01);
end = jiffies + 3*HZ;
while(INREG8(serverworks_private.registers,
SVWRKS_POSTFLUSH) == 0x01) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "Posted write buffer flush took more"
"then 3 seconds\n");
}
}
OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 0x00000001);
end = jiffies + 3*HZ;
while(INREG32(serverworks_private.registers,
SVWRKS_DIRFLUSH) == 0x00000001) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "TLB flush took more"
"then 3 seconds\n");
}
}
}
static int serverworks_configure(void) static int serverworks_configure(void)
{ {
struct aper_size_info_lvl2 *current_size; struct aper_size_info_lvl2 *current_size;
...@@ -253,7 +284,7 @@ static int serverworks_configure(void) ...@@ -253,7 +284,7 @@ static int serverworks_configure(void)
enable_reg |= 0x1; /* Agp Enable bit */ enable_reg |= 0x1; /* Agp Enable bit */
pci_write_config_byte(serverworks_private.svrwrks_dev, pci_write_config_byte(serverworks_private.svrwrks_dev,
SVWRKS_AGP_ENABLE, enable_reg); SVWRKS_AGP_ENABLE, enable_reg);
agp_bridge->tlb_flush(NULL); serverworks_tlbflush(NULL);
agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP); agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP);
...@@ -277,43 +308,11 @@ static void serverworks_cleanup(void) ...@@ -277,43 +308,11 @@ static void serverworks_cleanup(void)
iounmap((void *) serverworks_private.registers); iounmap((void *) serverworks_private.registers);
} }
/*
* This routine could be implemented by taking the addresses
* written to the GATT, and flushing them individually. However
* currently it just flushes the whole table. Which is probably
* more efficent, since agp_memory blocks can be a large number of
* entries.
*/
static void serverworks_tlbflush(agp_memory * temp)
{
unsigned long end;
OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 0x01);
end = jiffies + 3*HZ;
while(INREG8(serverworks_private.registers,
SVWRKS_POSTFLUSH) == 0x01) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "Posted write buffer flush took more"
"then 3 seconds\n");
}
}
OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 0x00000001);
end = jiffies + 3*HZ;
while(INREG32(serverworks_private.registers,
SVWRKS_DIRFLUSH) == 0x00000001) {
if((signed)(end - jiffies) <= 0) {
printk(KERN_ERR "TLB flush took more"
"then 3 seconds\n");
}
}
}
static unsigned long serverworks_mask_memory(unsigned long addr, int type) static unsigned long serverworks_mask_memory(unsigned long addr, int type)
{ {
/* Only type 0 is supported by the serverworks chipsets */ /* Only type 0 is supported by the serverworks chipsets */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
static int serverworks_insert_memory(agp_memory * mem, static int serverworks_insert_memory(agp_memory * mem,
...@@ -351,9 +350,9 @@ static int serverworks_insert_memory(agp_memory * mem, ...@@ -351,9 +350,9 @@ static int serverworks_insert_memory(agp_memory * mem,
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(addr); cur_gatt = SVRWRKS_GET_GATT(addr);
cur_gatt[GET_GATT_OFF(addr)] = cur_gatt[GET_GATT_OFF(addr)] =
agp_bridge->mask_memory(mem->memory[i], mem->type); agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
} }
agp_bridge->tlb_flush(mem); serverworks_tlbflush(mem);
return 0; return 0;
} }
...@@ -369,7 +368,7 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start, ...@@ -369,7 +368,7 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start,
} }
global_cache_flush(); global_cache_flush();
agp_bridge->tlb_flush(mem); serverworks_tlbflush(mem);
for (i = pg_start; i < (mem->page_count + pg_start); i++) { for (i = pg_start; i < (mem->page_count + pg_start); i++) {
addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
...@@ -378,7 +377,7 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start, ...@@ -378,7 +377,7 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start,
(unsigned long) agp_bridge->scratch_page; (unsigned long) agp_bridge->scratch_page;
} }
agp_bridge->tlb_flush(mem); serverworks_tlbflush(mem);
return 0; return 0;
} }
...@@ -420,13 +419,12 @@ static void serverworks_agp_enable(u32 mode) ...@@ -420,13 +419,12 @@ static void serverworks_agp_enable(u32 mode)
agp_device_command(command, 0); agp_device_command(command, 0);
} }
struct agp_bridge_data sworks_bridge = { struct agp_bridge_driver sworks_driver = {
.type = SVWRKS_GENERIC, .owner = THIS_MODULE,
.masks = serverworks_masks, .masks = serverworks_masks,
.aperture_sizes = (void *)serverworks_sizes, .aperture_sizes = serverworks_sizes,
.size_type = LVL2_APER_SIZE, .size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7, .num_aperture_sizes = 7,
.dev_private_data = &serverworks_private,
.configure = serverworks_configure, .configure = serverworks_configure,
.fetch_size = serverworks_fetch_size, .fetch_size = serverworks_fetch_size,
.cleanup = serverworks_cleanup, .cleanup = serverworks_cleanup,
...@@ -446,13 +444,10 @@ struct agp_bridge_data sworks_bridge = { ...@@ -446,13 +444,10 @@ struct agp_bridge_data sworks_bridge = {
.resume = agp_generic_resume, .resume = agp_generic_resume,
}; };
static struct agp_driver serverworks_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_serverworks_probe(struct pci_dev *pdev, static int __init agp_serverworks_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_bridge_data *bridge;
struct pci_dev *bridge_dev; struct pci_dev *bridge_dev;
u32 temp, temp2; u32 temp, temp2;
...@@ -466,8 +461,6 @@ static int __init agp_serverworks_probe(struct pci_dev *pdev, ...@@ -466,8 +461,6 @@ static int __init agp_serverworks_probe(struct pci_dev *pdev,
return -ENODEV; return -ENODEV;
} }
sworks_bridge.dev = pdev;
switch (pdev->device) { switch (pdev->device) {
case PCI_DEVICE_ID_SERVERWORKS_HE: case PCI_DEVICE_ID_SERVERWORKS_HE:
case PCI_DEVICE_ID_SERVERWORKS_LE: case PCI_DEVICE_ID_SERVERWORKS_LE:
...@@ -505,15 +498,24 @@ static int __init agp_serverworks_probe(struct pci_dev *pdev, ...@@ -505,15 +498,24 @@ static int __init agp_serverworks_probe(struct pci_dev *pdev,
} }
} }
memcpy(agp_bridge, &sworks_bridge, sizeof(struct agp_bridge_data)); bridge = agp_alloc_bridge();
serverworks_agp_driver.dev = pdev; if (!bridge)
agp_register_driver(&serverworks_agp_driver); return -ENOMEM;
return 0;
bridge->driver = &sworks_driver;
bridge->dev_private_data = &serverworks_private,
bridge->dev = pdev;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
} }
static void __exit agp_serverworks_remove(struct pci_dev *pdev) static void __exit agp_serverworks_remove(struct pci_dev *pdev)
{ {
agp_unregister_driver(&serverworks_agp_driver); struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
} }
static struct pci_device_id agp_serverworks_pci_table[] __initdata = { static struct pci_device_id agp_serverworks_pci_table[] __initdata = {
......
...@@ -18,9 +18,9 @@ static int via_fetch_size(void) ...@@ -18,9 +18,9 @@ static int via_fetch_size(void)
u8 temp; u8 temp;
struct aper_size_info_8 *values; struct aper_size_info_8 *values;
values = A_SIZE_8(agp_bridge->aperture_sizes); values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp); pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -79,7 +79,7 @@ static unsigned long via_mask_memory(unsigned long addr, int type) ...@@ -79,7 +79,7 @@ static unsigned long via_mask_memory(unsigned long addr, int type)
{ {
/* Memory type is ignored */ /* Memory type is ignored */
return addr | agp_bridge->masks[0].mask; return addr | agp_bridge->driver->masks[0].mask;
} }
...@@ -107,11 +107,11 @@ static int via_fetch_size_agp3(void) ...@@ -107,11 +107,11 @@ static int via_fetch_size_agp3(void)
u16 temp; u16 temp;
struct aper_size_info_16 *values; struct aper_size_info_16 *values;
values = A_SIZE_16(agp_bridge->aperture_sizes); values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp); pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp);
temp &= 0xfff; temp &= 0xfff;
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) { if (temp == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i); agp_bridge->current_size = (void *) (values + i);
...@@ -174,10 +174,10 @@ static struct aper_size_info_16 via_generic_agp3_sizes[11] = ...@@ -174,10 +174,10 @@ static struct aper_size_info_16 via_generic_agp3_sizes[11] =
{ 2048, 524288, 9, 1<<11} /* 2GB <- Max supported */ { 2048, 524288, 9, 1<<11} /* 2GB <- Max supported */
}; };
struct agp_bridge_data via_generic_agp3_bridge = { struct agp_bridge_driver via_agp3_driver = {
.type = VIA_GENERIC, .owner = THIS_MODULE,
.masks = via_generic_masks, .masks = via_generic_masks,
.aperture_sizes = (void *)via_generic_agp3_sizes, .aperture_sizes = via_generic_agp3_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
.num_aperture_sizes = 10, .num_aperture_sizes = 10,
.configure = via_configure_agp3, .configure = via_configure_agp3,
...@@ -199,10 +199,10 @@ struct agp_bridge_data via_generic_agp3_bridge = { ...@@ -199,10 +199,10 @@ struct agp_bridge_data via_generic_agp3_bridge = {
.resume = agp_generic_resume, .resume = agp_generic_resume,
}; };
struct agp_bridge_data via_generic_bridge = { struct agp_bridge_driver via_driver = {
.type = VIA_GENERIC, .owner = THIS_MODULE,
.masks = via_generic_masks, .masks = via_generic_masks,
.aperture_sizes = (void *)via_generic_sizes, .aperture_sizes = via_generic_sizes,
.size_type = U8_APER_SIZE, .size_type = U8_APER_SIZE,
.num_aperture_sizes = 7, .num_aperture_sizes = 7,
.configure = via_configure, .configure = via_configure,
...@@ -363,16 +363,11 @@ static struct agp_device_ids via_agp_device_ids[] __initdata = ...@@ -363,16 +363,11 @@ static struct agp_device_ids via_agp_device_ids[] __initdata =
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
static struct agp_driver via_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_via_probe(struct pci_dev *pdev, static int __init agp_via_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
struct agp_device_ids *devs = via_agp_device_ids; struct agp_device_ids *devs = via_agp_device_ids;
struct agp_bridge_data *bridge = &via_generic_bridge; struct agp_bridge_data *bridge;
int j = 0; int j = 0;
u8 cap_ptr, reg; u8 cap_ptr, reg;
...@@ -401,6 +396,13 @@ static int __init agp_via_probe(struct pci_dev *pdev, ...@@ -401,6 +396,13 @@ static int __init agp_via_probe(struct pci_dev *pdev,
" for device id: %04x\n", pdev->device); " for device id: %04x\n", pdev->device);
found: found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
switch (pdev->device) { switch (pdev->device) {
case PCI_DEVICE_ID_VIA_8367_0: case PCI_DEVICE_ID_VIA_8367_0:
/* /*
...@@ -420,9 +422,13 @@ static int __init agp_via_probe(struct pci_dev *pdev, ...@@ -420,9 +422,13 @@ static int __init agp_via_probe(struct pci_dev *pdev,
pci_read_config_byte(pdev, VIA_AGPSEL, &reg); pci_read_config_byte(pdev, VIA_AGPSEL, &reg);
/* Check AGP 2.0 compatibility mode. */ /* Check AGP 2.0 compatibility mode. */
if ((reg & (1<<1))==0) { if ((reg & (1<<1))==0) {
bridge = &via_generic_agp3_bridge; bridge->driver = &via_agp3_driver;
break; break;
} }
/*FALLTHROUGH*/
default:
bridge->driver = &via_driver;
break;
} }
...@@ -433,11 +439,16 @@ static int __init agp_via_probe(struct pci_dev *pdev, ...@@ -433,11 +439,16 @@ static int __init agp_via_probe(struct pci_dev *pdev,
pci_read_config_dword(pdev, pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS, &bridge->mode); bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
memcpy(agp_bridge, bridge, sizeof(struct agp_bridge_data)); pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __exit agp_via_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
via_agp_driver.dev = pdev; agp_remove_bridge(bridge);
agp_register_driver(&via_agp_driver); agp_put_bridge(bridge);
return 0;
} }
static struct pci_device_id agp_via_pci_table[] __initdata = { static struct pci_device_id agp_via_pci_table[] __initdata = {
......
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