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 {
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_version *version;
void *aperture_sizes;
struct agp_bridge_driver *driver;
struct vm_operations_struct *vm_ops;
void *previous_size;
void *current_size;
void *dev_private_data;
struct pci_dev *dev;
struct gatt_mask *masks;
u32 *gatt_table;
u32 *gatt_table_real;
unsigned long scratch_page;
......@@ -99,38 +126,12 @@ struct agp_bridge_data {
unsigned long gatt_bus_addr;
u32 mode;
enum chipset_type type;
enum aper_size_type size_type;
unsigned long *key_list;
atomic_t current_memory_agp;
atomic_t agp_in_use;
int max_memory_agp; /* in number of pages */
int needs_scratch_page;
int aperture_size_idx;
int num_aperture_sizes;
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))
......@@ -152,9 +153,9 @@ struct agp_bridge_data {
#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_FIX(x) ((struct aper_size_info_fixed *) x)
#define A_IDX8(bridge) (A_SIZE_8((bridge)->aperture_sizes) + i)
#define A_IDX16(bridge) (A_SIZE_16((bridge)->aperture_sizes) + i)
#define A_IDX32(bridge) (A_SIZE_32((bridge)->aperture_sizes) + i)
#define A_IDX8(bridge) (A_SIZE_8((bridge)->driver->aperture_sizes) + i)
#define A_IDX16(bridge) (A_SIZE_16((bridge)->driver->aperture_sizes) + i)
#define A_IDX32(bridge) (A_SIZE_32((bridge)->driver->aperture_sizes) + i)
#define MAXKEY (4096 * 32)
#define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page)
......@@ -353,20 +354,16 @@ struct agp_device_ids {
int (*chipset_setup) (struct pci_dev *pdev); /* used to override generic */
};
struct agp_driver {
struct module *owner;
struct pci_dev *dev;
};
/* Driver registration */
struct agp_bridge_data *agp_alloc_bridge(void);
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);
/* Backend routines. */
int agp_register_driver (struct agp_driver *drv);
int agp_unregister_driver(struct agp_driver *drv);
/* Generic routines. */
void agp_generic_enable(u32 mode);
int agp_generic_create_gatt_table(void);
......
......@@ -19,9 +19,9 @@ static int ali_fetch_size(void)
pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
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) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
......@@ -118,7 +118,7 @@ static unsigned long ali_mask_memory(unsigned long addr, int type)
{
/* 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)
......@@ -196,10 +196,10 @@ static struct aper_size_info_32 ali_generic_sizes[7] =
{4, 1024, 0, 3}
};
struct agp_bridge_data ali_generic_bridge = {
.type = ALI_GENERIC,
struct agp_bridge_driver ali_generic_bridge = {
.owner = THIS_MODULE,
.masks = ali_generic_masks,
.aperture_sizes = (void *)ali_generic_sizes,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = ali_configure,
......@@ -221,10 +221,10 @@ struct agp_bridge_data ali_generic_bridge = {
.resume = agp_generic_resume,
};
struct agp_bridge_data ali_m1541_bridge = {
.type = ALI_GENERIC,
struct agp_bridge_driver ali_m1541_bridge = {
.owner = THIS_MODULE,
.masks = ali_generic_masks,
.aperture_sizes = (void *)ali_generic_sizes,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = ali_configure,
......@@ -288,10 +288,6 @@ struct agp_device_ids ali_agp_device_ids[] __initdata =
{ }, /* 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,
const struct pci_device_id *ent)
{
......@@ -320,13 +316,18 @@ static int __init agp_ali_probe(struct pci_dev *pdev,
printk(KERN_WARNING PFX "Trying generic ALi routines"
" for device id: %04x\n", pdev->device);
bridge = &ali_generic_bridge;
goto generic;
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
switch (pdev->device) {
case PCI_DEVICE_ID_AL_M1541:
bridge = &ali_m1541_bridge;
bridge->driver = &ali_m1541_bridge;
break;
case PCI_DEVICE_ID_AL_M1621:
pci_read_config_byte(pdev, 0xFB, &hidden_1621_id);
......@@ -351,31 +352,29 @@ static int __init agp_ali_probe(struct pci_dev *pdev,
default:
break;
}
/*FALLTHROUGH*/
default:
bridge = &ali_generic_bridge;
bridge->driver = &ali_generic_bridge;
}
printk(KERN_INFO PFX "Detected ALi %s chipset\n",
devs[j].chipset_name);
generic:
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
memcpy(agp_bridge, bridge, sizeof(struct agp_bridge_data));
ali_agp_driver.dev = pdev;
agp_register_driver(&ali_agp_driver);
return 0;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
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 = {
......
......@@ -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)
{
/* 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)
......@@ -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);
mb();
agp_bridge->tlb_flush(mem);
alpha_core_agp_tlbflush(mem);
return status;
}
......@@ -121,23 +121,17 @@ static int alpha_core_agp_remove_memory(agp_memory *mem, off_t pg_start,
int status;
status = agp->ops->unbind(agp, pg_start, mem);
agp_bridge->tlb_flush(mem);
alpha_core_agp_tlbflush(mem);
return status;
}
static struct agp_driver alpha_core_agp_driver = {
.owner = THIS_MODULE,
};
struct agp_bridge_data alpha_core_agp_bridge = {
.type = ALPHA_CORE_AGP,
struct agp_bridge_driver alpha_core_agp_driver = {
.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,
.dev_private_data = agp,
.configure = alpha_core_agp_configure,
.fetch_size = alpha_core_agp_fetch_size,
.cleanup = alpha_core_agp_cleanup,
......@@ -158,6 +152,8 @@ struct agp_bridge_data alpha_core_agp_bridge = {
.vm_ops = &alpha_core_agp_vm_ops,
};
struct agp_bridge_data *alpha_bridge;
int __init
alpha_core_agp_setup(void)
{
......@@ -190,14 +186,20 @@ alpha_core_agp_setup(void)
pdev->device = 0xffff;
pdev->sysdata = agp->hose;
alpha_core_agp_bridge.dev = pdev;
memcpy(agp_bridge, &alpha_core_agp_bridge,
sizeof(struct agp_bridge_data));
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;
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);
return 0;
return agp_add_bridge(alpha_bridge);
fail:
kfree(pdev);
return -ENOMEM;
}
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)
{
agp_unregister_driver(&alpha_core_agp_driver);
/* no pci driver for core */
agp_remove_bridge(alpha_bridge);
agp_put_bridge(alpha_bridge);
}
module_init(agp_alpha_core_init);
......
......@@ -184,8 +184,8 @@ static int amd_irongate_fetch_size(void)
pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
temp = (temp & 0x0000000e);
values = A_SIZE_LVL2(agp_bridge->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
......@@ -274,7 +274,7 @@ static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
{
/* 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,
......@@ -311,9 +311,9 @@ static int amd_insert_memory(agp_memory * mem,
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(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;
}
......@@ -334,7 +334,7 @@ static int amd_remove_memory(agp_memory * mem, off_t pg_start,
(unsigned long) agp_bridge->scratch_page;
}
agp_bridge->tlb_flush(mem);
amd_irongate_tlbflush(mem);
return 0;
}
......@@ -354,13 +354,12 @@ static struct gatt_mask amd_irongate_masks[] =
{.mask = 0x00000001, .type = 0}
};
struct agp_bridge_data amd_irongate_bridge = {
.type = AMD_GENERIC,
struct agp_bridge_driver amd_irongate_driver = {
.owner = THIS_MODULE,
.masks = amd_irongate_masks,
.aperture_sizes = (void *)amd_irongate_sizes,
.aperture_sizes = amd_irongate_sizes,
.size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7,
.dev_private_data = (void *)&amd_irongate_private,
.configure = amd_irongate_configure,
.fetch_size = amd_irongate_fetch_size,
.cleanup = amd_irongate_cleanup,
......@@ -397,14 +396,11 @@ struct agp_device_ids amd_agp_device_ids[] __initdata =
{ }, /* 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,
const struct pci_device_id *ent)
{
struct agp_device_ids *devs = amd_agp_device_ids;
struct agp_bridge_data *bridge;
u8 cap_ptr;
int j;
......@@ -416,7 +412,6 @@ static int __init agp_amdk7_probe(struct pci_dev *pdev,
if (pdev->device == devs[j].device_id) {
printk (KERN_INFO PFX "Detected AMD %s chipset\n",
devs[j].chipset_name);
amd_irongate_bridge.type = devs[j].chipset;
goto found;
}
}
......@@ -433,24 +428,30 @@ static int __init agp_amdk7_probe(struct pci_dev *pdev,
" for device id: %04x\n", pdev->device);
found:
amd_irongate_bridge.dev = pdev;
amd_irongate_bridge.capndx = cap_ptr;
bridge = agp_alloc_bridge();
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 */
pci_read_config_dword(pdev,
amd_irongate_bridge.capndx+PCI_AGP_STATUS,
&amd_irongate_bridge.mode);
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
memcpy(agp_bridge, &amd_irongate_bridge, sizeof(struct agp_bridge_data));
amd_k7_agp_driver.dev = pdev;
agp_register_driver(&amd_k7_agp_driver);
return 0;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
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 = {
......@@ -489,4 +490,3 @@ module_exit(agp_amdk7_cleanup);
MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
......@@ -29,6 +29,21 @@ static struct pci_dev * hammers[MAX_HAMMER_GARTS];
static int 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)
{
int i, j, num_entries;
......@@ -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++) {
addr = agp_bridge->mask_memory(mem->memory[i], mem->type);
addr = agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
tmp = addr;
BUG_ON(tmp & 0xffffff0000000ffc);
......@@ -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->tlb_flush(mem);
amd_x86_64_tlbflush(mem);
return 0;
}
......@@ -113,7 +128,7 @@ static int amd_x86_64_fetch_size(void)
temp = (temp & 0xe);
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) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
......@@ -125,25 +140,6 @@ static int amd_x86_64_fetch_size(void)
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
* called once for each CPU.
......@@ -218,7 +214,7 @@ static void amd_8151_cleanup(void)
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[] =
{.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,
.aperture_sizes = (void *)amd_8151_sizes,
.aperture_sizes = amd_8151_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = amd_8151_configure,
......@@ -251,13 +248,10 @@ struct agp_bridge_data amd_8151_bridge = {
.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,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
struct pci_dev *loop_dev;
u8 cap_ptr;
int i = 0;
......@@ -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");
amd_8151_bridge.dev = pdev;
amd_8151_bridge.capndx = cap_ptr;
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &amd_8151_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev,
amd_8151_bridge.capndx+PCI_AGP_STATUS,
&amd_8151_bridge.mode);
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
/* cache pci_devs of northbridges. */
pci_for_each_dev(loop_dev) {
......@@ -285,20 +284,23 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
hammers[i++] = loop_dev;
nr_garts = i;
if (i == MAX_HAMMER_GARTS)
return 0;
goto out_free;
}
}
memcpy(agp_bridge, &amd_8151_bridge, sizeof(struct agp_bridge_data));
amd_k8_agp_driver.dev = pdev;
agp_register_driver(&amd_k8_agp_driver);
return 0;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
out_free:
agp_put_bridge(bridge);
return -ENOMEM;
}
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 = {
......
......@@ -130,8 +130,8 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
bridge->max_memory_agp = agp_find_max();
bridge->version = &agp_current_version;
if (bridge->needs_scratch_page) {
void *addr = bridge->agp_alloc_page();
if (bridge->driver->needs_scratch_page) {
void *addr = bridge->driver->agp_alloc_page();
if (!addr) {
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)
bridge->scratch_page_real = virt_to_phys(addr);
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) {
printk(KERN_ERR PFX "unable to determine aperture size.\n");
rc = -EINVAL;
goto err_out;
}
if (bridge->create_gatt_table()) {
if (bridge->driver->create_gatt_table()) {
printk(KERN_ERR PFX
"unable to get memory for graphics translation table.\n");
rc = -ENOMEM;
......@@ -168,7 +168,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
/* FIXME vmalloc'd memory not guaranteed contiguous */
memset(bridge->key_list, 0, PAGE_SIZE * 4);
if (bridge->configure()) {
if (bridge->driver->configure()) {
printk(KERN_ERR PFX "error configuring host chipset.\n");
rc = -EINVAL;
goto err_out;
......@@ -180,10 +180,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
return 0;
err_out:
if (bridge->needs_scratch_page)
bridge->agp_destroy_page(phys_to_virt(bridge->scratch_page_real));
if (bridge->driver->needs_scratch_page)
bridge->driver->agp_destroy_page(
phys_to_virt(bridge->scratch_page_real));
if (got_gatt)
bridge->free_gatt_table();
bridge->driver->free_gatt_table();
if (got_keylist)
vfree(bridge->key_list);
return rc;
......@@ -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 */
static void agp_backend_cleanup(struct agp_bridge_data *bridge)
{
if (bridge->cleanup)
bridge->cleanup();
if (bridge->free_gatt_table)
bridge->free_gatt_table();
if (bridge->driver->cleanup)
bridge->driver->cleanup();
if (bridge->driver->free_gatt_table)
bridge->driver->free_gatt_table();
if (bridge->key_list)
vfree(bridge->key_list);
if (bridge->agp_destroy_page && bridge->needs_scratch_page)
bridge->agp_destroy_page(
if (bridge->driver->agp_destroy_page &&
bridge->driver->needs_scratch_page)
bridge->driver->agp_destroy_page(
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)
{
switch(rq) {
case PM_SUSPEND:
return agp_bridge->suspend();
return agp_bridge->driver->suspend();
case PM_RESUME:
agp_bridge->resume();
agp_bridge->driver->resume();
return 0;
}
return 0;
......@@ -228,66 +230,77 @@ static const drm_agp_t drm_agp = {
&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) {
printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
if (!bridge->dev) {
printk(KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
return -EINVAL;
}
if (agp_count==1) {
printk (KERN_DEBUG PFX "Only one agpgart device currently supported.\n");
if (agp_count) {
printk(KERN_DEBUG PFX
"Only one agpgart device currently supported.\n");
return -ENODEV;
}
/* Grab reference on the chipset driver. */
if (!try_module_get(drv->owner))
if (!try_module_get(bridge->driver->owner))
return -EINVAL;
ret_val = agp_backend_initialize(agp_bridge);
if (ret_val)
bridge->type = SUPPORTED;
error = agp_backend_initialize(agp_bridge);
if (error)
goto err_out;
ret_val = agp_frontend_initialize();
if (ret_val)
error = agp_frontend_initialize();
if (error)
goto frontend_err;
/* FIXME: What to do with this? */
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++;
return 0;
frontend_err:
agp_backend_cleanup(agp_bridge);
err_out:
agp_bridge->type = NOT_SUPPORTED;
module_put(drv->owner);
drv->dev = NULL;
return ret_val;
bridge->type = NOT_SUPPORTED;
module_put(bridge->driver->owner);
return error;
}
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)
return -ENODEV;
agp_bridge->type = NOT_SUPPORTED;
bridge->type = NOT_SUPPORTED;
pm_unregister_all(agp_power);
agp_frontend_cleanup();
agp_backend_cleanup(agp_bridge);
agp_backend_cleanup(bridge);
inter_module_unregister("drm_agp");
agp_count--;
module_put(drv->owner);
return 0;
module_put(bridge->driver->owner);
}
EXPORT_SYMBOL_GPL(agp_unregister_driver);
EXPORT_SYMBOL_GPL(agp_remove_bridge);
static int __init agp_init(void)
......
......@@ -116,12 +116,12 @@ void agp_free_memory(agp_memory * curr)
agp_unbind_memory(curr);
if (curr->type != 0) {
agp_bridge->free_by_type(curr);
agp_bridge->driver->free_by_type(curr);
return;
}
if (curr->page_count != 0) {
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);
......@@ -156,7 +156,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return NULL;
if (type != 0) {
new = agp_bridge->alloc_by_type(page_count, type);
new = agp_bridge->driver->alloc_by_type(page_count, type);
return new;
}
......@@ -168,7 +168,7 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return NULL;
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) {
agp_free_memory(new);
......@@ -195,7 +195,7 @@ static int agp_return_size(void)
temp = agp_bridge->current_size;
switch (agp_bridge->size_type) {
switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE:
current_size = A_SIZE_8(temp)->size;
break;
......@@ -230,7 +230,7 @@ int agp_num_entries(void)
temp = agp_bridge->current_size;
switch (agp_bridge->size_type) {
switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE:
num_entries = A_SIZE_8(temp)->num_entries;
break;
......@@ -283,7 +283,7 @@ int agp_copy_info(agp_kern_info * info)
info->aper_size = agp_return_size();
info->max_memory = agp_bridge->max_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->page_mask = ~0UL;
return 0;
......@@ -318,10 +318,10 @@ int agp_bind_memory(agp_memory * curr, off_t pg_start)
return -EINVAL;
}
if (curr->is_flushed == FALSE) {
agp_bridge->cache_flush();
agp_bridge->driver->cache_flush();
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)
return ret_val;
......@@ -351,7 +351,7 @@ int agp_unbind_memory(agp_memory * curr)
if (curr->is_bound != TRUE)
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)
return ret_val;
......@@ -494,7 +494,7 @@ int agp_generic_create_gatt_table(void)
struct page *page;
/* 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;
table = NULL;
......@@ -502,9 +502,9 @@ int agp_generic_create_gatt_table(void)
temp = agp_bridge->current_size;
size = page_order = num_entries = 0;
if (agp_bridge->size_type != FIXED_APER_SIZE) {
if (agp_bridge->driver->size_type != FIXED_APER_SIZE) {
do {
switch (agp_bridge->size_type) {
switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE:
size = A_SIZE_8(temp)->size;
page_order =
......@@ -535,7 +535,7 @@ int agp_generic_create_gatt_table(void)
if (table == NULL) {
i++;
switch (agp_bridge->size_type) {
switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE:
agp_bridge->current_size = A_IDX8(agp_bridge);
break;
......@@ -557,7 +557,7 @@ int agp_generic_create_gatt_table(void)
} else {
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 {
size = ((struct aper_size_info_fixed *) temp)->size;
page_order = ((struct aper_size_info_fixed *) temp)->page_order;
......@@ -576,10 +576,10 @@ int agp_generic_create_gatt_table(void)
agp_bridge->gatt_table_real = (u32 *) 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),
(PAGE_SIZE * (1 << page_order)));
agp_bridge->cache_flush();
agp_bridge->driver->cache_flush();
if (agp_bridge->gatt_table == NULL) {
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
......@@ -623,7 +623,7 @@ int agp_generic_free_gatt_table(void)
temp = agp_bridge->current_size;
switch (agp_bridge->size_type) {
switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE:
page_order = A_SIZE_8(temp)->page_order;
break;
......@@ -671,7 +671,7 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
temp = agp_bridge->current_size;
switch (agp_bridge->size_type) {
switch (agp_bridge->driver->size_type) {
case U8_APER_SIZE:
num_entries = A_SIZE_8(temp)->num_entries;
break;
......@@ -715,15 +715,16 @@ int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
}
if (mem->is_flushed == FALSE) {
agp_bridge->cache_flush();
agp_bridge->driver->cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, 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;
}
EXPORT_SYMBOL(agp_generic_insert_memory);
......@@ -744,7 +745,7 @@ int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
(unsigned long) agp_bridge->scratch_page;
}
agp_bridge->tlb_flush(mem);
agp_bridge->driver->tlb_flush(mem);
return 0;
}
EXPORT_SYMBOL(agp_generic_remove_memory);
......@@ -821,7 +822,7 @@ void agp_enable(u32 mode)
{
if (agp_bridge->type == NOT_SUPPORTED)
return;
agp_bridge->agp_enable(mode);
agp_bridge->driver->agp_enable(mode);
}
EXPORT_SYMBOL(agp_enable);
......
......@@ -296,11 +296,11 @@ static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type)
for (k = 0;
k < hp->io_pages_per_kpage;
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;
}
......@@ -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;
}
agp_bridge->tlb_flush(mem);
agp_bridge->driver->tlb_flush(mem);
return 0;
}
......@@ -328,8 +328,8 @@ static unsigned long hp_zx1_mask_memory(unsigned long addr, int type)
return HP_ZX1_PDIR_VALID_BIT | addr;
}
struct agp_bridge_data hp_zx1_bridge = {
.type = HP_ZX1,
struct agp_bridge_driver hp_zx1_driver = {
.owner = THIS_MODULE,
.masks = hp_zx1_masks,
.size_type = FIXED_APER_SIZE,
.configure = hp_zx1_configure,
......@@ -350,13 +350,10 @@ struct agp_bridge_data hp_zx1_bridge = {
.cant_use_aperture = 1,
};
static struct agp_driver hp_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_hp_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
int error;
/* ZX1 LBAs can be either PCI or AGP bridges */
......@@ -369,18 +366,24 @@ static int __init agp_hp_probe(struct pci_dev *pdev,
error = hp_zx1_ioc_init();
if (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;
agp_register_driver(&hp_agp_driver);
return 0;
bridge->driver = &hp_zx1_driver;
bridge->dev = pdev;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
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 = {
......
......@@ -69,7 +69,7 @@ static struct {
} *lp_desc;
} 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
......@@ -107,7 +107,7 @@ static int i460_fetch_size (void)
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);
......@@ -130,7 +130,7 @@ static int i460_fetch_size (void)
else
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
* the define aperture sizes. Take care not to shift off the end of
......@@ -140,7 +140,7 @@ static int i460_fetch_size (void)
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 */
if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) {
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
for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
paddr = mem->memory[i];
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);
return 0;
......@@ -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)
return -ENOMEM;
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);
}
......@@ -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;
void *temp;
temp = agp_bridge->current_size;
temp = agp_bridge->driver->current_size;
num_entries = A_SIZE_8(temp)->num_entries;
/* Figure out what pg_start means in terms of our large GART pages */
......@@ -519,13 +519,14 @@ static void i460_destroy_page (void *page)
static unsigned long i460_mask_memory (unsigned long addr, int type)
{
/* 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));
}
struct agp_bridge_data intel_i460_bridge = {
struct agp_bridge_driver intel_i460_driver = {
.owner = THIS_MODULE,
.masks = i460_masks,
.aperture_sizes = (void *)i460_sizes,
.aperture_sizes = i460_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 3,
.configure = i460_configure,
......@@ -555,32 +556,34 @@ struct agp_bridge_data intel_i460_bridge = {
.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,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
intel_i460_bridge.dev = pdev;
intel_i460_bridge.capndx = cap_ptr;
bridge = agp_alloc_bridge();
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;
agp_register_driver(&i460_agp_driver);
return 0;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
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 = {
......
This diff is collapsed.
......@@ -47,9 +47,9 @@ static int nvidia_fetch_size(void)
pci_read_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE, &size_value);
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) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
......@@ -143,7 +143,7 @@ static void nvidia_cleanup(void)
static unsigned long nvidia_mask_memory(unsigned long addr, int type)
{
/* Memory type is ignored */
return addr | agp_bridge->masks[0].mask;
return addr | agp_bridge->driver->masks[0].mask;
}
#if 0
......@@ -242,13 +242,12 @@ static struct gatt_mask nvidia_generic_masks[] =
};
struct agp_bridge_data nvidia_bridge = {
.type = NVIDIA_GENERIC,
struct agp_bridge_driver nvidia_driver = {
.owner = THIS_MODULE,
.masks = nvidia_generic_masks,
.aperture_sizes = (void *) nvidia_generic_sizes,
.aperture_sizes = nvidia_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 5,
.dev_private_data = (void *) &nvidia_private,
.configure = nvidia_configure,
.fetch_size = nvidia_fetch_size,
.cleanup = nvidia_cleanup,
......@@ -268,14 +267,10 @@ struct agp_bridge_data nvidia_bridge = {
.resume = agp_generic_resume,
};
static struct agp_driver nvidia_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_nvidia_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
nvidia_private.dev_1 =
......@@ -319,24 +314,30 @@ static int __init agp_nvidia_probe(struct pci_dev *pdev,
break;
}
nvidia_bridge.dev = pdev;
nvidia_bridge.capndx = cap_ptr;
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &nvidia_driver;
bridge->dev_private_data = &nvidia_private,
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev,
nvidia_bridge.capndx+PCI_AGP_STATUS,
&nvidia_bridge.mode);
memcpy(agp_bridge, &nvidia_bridge, sizeof(struct agp_bridge_data));
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
nvidia_agp_driver.dev = pdev;
agp_register_driver(&nvidia_agp_driver);
return 0;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
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 = {
......
......@@ -17,8 +17,8 @@ static int sis_fetch_size(void)
struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, SIS_APSIZE, &temp_size);
values = A_SIZE_8(agp_bridge->aperture_sizes);
for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if ((temp_size == values[i].size_value) ||
((temp_size & ~(0x03)) ==
(values[i].size_value & ~(0x03)))) {
......@@ -67,7 +67,7 @@ static unsigned long sis_mask_memory(unsigned long addr, int type)
{
/* 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] =
......@@ -86,10 +86,10 @@ static struct gatt_mask sis_generic_masks[] =
{.mask = 0x00000000, .type = 0}
};
struct agp_bridge_data sis_generic_bridge = {
.type = SIS_GENERIC,
struct agp_bridge_driver sis_driver = {
.owner = THIS_MODULE,
.masks = sis_generic_masks,
.aperture_sizes = (void *)sis_generic_sizes,
.aperture_sizes = sis_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 7,
.configure = sis_configure,
......@@ -168,14 +168,11 @@ struct agp_device_ids sis_agp_device_ids[] __initdata =
{ }, /* 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,
const struct pci_device_id *ent)
{
struct agp_device_ids *devs = sis_agp_device_ids;
struct agp_bridge_data *bridge;
u8 cap_ptr;
int j;
......@@ -204,23 +201,29 @@ static int __init agp_sis_probe(struct pci_dev *pdev,
" for device id: %04x\n", pdev->device);
found:
sis_generic_bridge.dev = pdev;
sis_generic_bridge.capndx = cap_ptr;
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &sis_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev, sis_generic_bridge.capndx+PCI_AGP_STATUS,
&sis_generic_bridge.mode);
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
memcpy(agp_bridge, &sis_generic_bridge,
sizeof(struct agp_bridge_data));
sis_agp_driver.dev = pdev;
agp_register_driver(&sis_agp_driver);
return 0;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
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 = {
......
......@@ -203,7 +203,7 @@ static int serverworks_fetch_size(void)
u32 temp2;
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_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,
SVWRKS_SIZE_MASK);
......@@ -211,7 +211,7 @@ static int serverworks_fetch_size(void)
pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp);
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) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
......@@ -224,6 +224,37 @@ static int serverworks_fetch_size(void)
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)
{
struct aper_size_info_lvl2 *current_size;
......@@ -253,7 +284,7 @@ static int serverworks_configure(void)
enable_reg |= 0x1; /* Agp Enable bit */
pci_write_config_byte(serverworks_private.svrwrks_dev,
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);
......@@ -277,43 +308,11 @@ static void serverworks_cleanup(void)
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)
{
/* 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,
......@@ -351,9 +350,9 @@ static int serverworks_insert_memory(agp_memory * mem,
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(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;
}
......@@ -369,7 +368,7 @@ static int serverworks_remove_memory(agp_memory * mem, off_t pg_start,
}
global_cache_flush();
agp_bridge->tlb_flush(mem);
serverworks_tlbflush(mem);
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
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,
(unsigned long) agp_bridge->scratch_page;
}
agp_bridge->tlb_flush(mem);
serverworks_tlbflush(mem);
return 0;
}
......@@ -420,13 +419,12 @@ static void serverworks_agp_enable(u32 mode)
agp_device_command(command, 0);
}
struct agp_bridge_data sworks_bridge = {
.type = SVWRKS_GENERIC,
struct agp_bridge_driver sworks_driver = {
.owner = THIS_MODULE,
.masks = serverworks_masks,
.aperture_sizes = (void *)serverworks_sizes,
.aperture_sizes = serverworks_sizes,
.size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7,
.dev_private_data = &serverworks_private,
.configure = serverworks_configure,
.fetch_size = serverworks_fetch_size,
.cleanup = serverworks_cleanup,
......@@ -446,13 +444,10 @@ struct agp_bridge_data sworks_bridge = {
.resume = agp_generic_resume,
};
static struct agp_driver serverworks_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_serverworks_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
struct pci_dev *bridge_dev;
u32 temp, temp2;
......@@ -466,8 +461,6 @@ static int __init agp_serverworks_probe(struct pci_dev *pdev,
return -ENODEV;
}
sworks_bridge.dev = pdev;
switch (pdev->device) {
case PCI_DEVICE_ID_SERVERWORKS_HE:
case PCI_DEVICE_ID_SERVERWORKS_LE:
......@@ -505,15 +498,24 @@ static int __init agp_serverworks_probe(struct pci_dev *pdev,
}
}
memcpy(agp_bridge, &sworks_bridge, sizeof(struct agp_bridge_data));
serverworks_agp_driver.dev = pdev;
agp_register_driver(&serverworks_agp_driver);
return 0;
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
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)
{
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 = {
......
......@@ -18,9 +18,9 @@ static int via_fetch_size(void)
u8 temp;
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);
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) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
......@@ -79,7 +79,7 @@ static unsigned long via_mask_memory(unsigned long addr, int type)
{
/* 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)
u16 temp;
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);
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) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
......@@ -174,10 +174,10 @@ static struct aper_size_info_16 via_generic_agp3_sizes[11] =
{ 2048, 524288, 9, 1<<11} /* 2GB <- Max supported */
};
struct agp_bridge_data via_generic_agp3_bridge = {
.type = VIA_GENERIC,
struct agp_bridge_driver via_agp3_driver = {
.owner = THIS_MODULE,
.masks = via_generic_masks,
.aperture_sizes = (void *)via_generic_agp3_sizes,
.aperture_sizes = via_generic_agp3_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 10,
.configure = via_configure_agp3,
......@@ -199,10 +199,10 @@ struct agp_bridge_data via_generic_agp3_bridge = {
.resume = agp_generic_resume,
};
struct agp_bridge_data via_generic_bridge = {
.type = VIA_GENERIC,
struct agp_bridge_driver via_driver = {
.owner = THIS_MODULE,
.masks = via_generic_masks,
.aperture_sizes = (void *)via_generic_sizes,
.aperture_sizes = via_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 7,
.configure = via_configure,
......@@ -363,16 +363,11 @@ static struct agp_device_ids via_agp_device_ids[] __initdata =
{ }, /* 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,
const struct pci_device_id *ent)
{
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;
u8 cap_ptr, reg;
......@@ -401,6 +396,13 @@ static int __init agp_via_probe(struct pci_dev *pdev,
" for device id: %04x\n", pdev->device);
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
switch (pdev->device) {
case PCI_DEVICE_ID_VIA_8367_0:
/*
......@@ -420,9 +422,13 @@ static int __init agp_via_probe(struct pci_dev *pdev,
pci_read_config_byte(pdev, VIA_AGPSEL, &reg);
/* Check AGP 2.0 compatibility mode. */
if ((reg & (1<<1))==0) {
bridge = &via_generic_agp3_bridge;
bridge->driver = &via_agp3_driver;
break;
}
/*FALLTHROUGH*/
default:
bridge->driver = &via_driver;
break;
}
......@@ -433,11 +439,16 @@ static int __init agp_via_probe(struct pci_dev *pdev,
pci_read_config_dword(pdev,
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_register_driver(&via_agp_driver);
return 0;
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
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