X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fchar%2Fagp%2Famd64-agp.c;h=eca1c4f7add8acca2f906b539d6a7971b03bd5a6;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=2e8b2aee99712bbd3bc3101a133ca1fdfacfad0e;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 2e8b2aee9..eca1c4f7a 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -46,6 +46,11 @@ #define NVIDIA_X86_64_1_APBASE2 0xd8 #define NVIDIA_X86_64_1_APLIMIT2 0xdc +/* ULi K8 registers */ +#define ULI_X86_64_BASE_ADDR 0x10 +#define ULI_X86_64_HTT_FEA_REG 0x50 +#define ULI_X86_64_ENU_SCR_REG 0x54 + static int nr_garts; static struct pci_dev * hammers[MAX_HAMMER_GARTS]; @@ -109,6 +114,7 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type) pte |= GPTE_VALID | GPTE_COHERENT; writel(pte, agp_bridge->gatt_table+j); + readl(agp_bridge->gatt_table+j); /* PCI Posting. */ } amd64_tlbflush(mem); return 0; @@ -355,7 +361,7 @@ static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr) int i = 0; /* cache pci_devs of northbridges. */ - while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) + while ((loop_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev)) != NULL) { if (i == MAX_HAMMER_GARTS) { printk(KERN_ERR PFX "Too many northbridges for AGP\n"); @@ -405,6 +411,61 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data } } + +static struct aper_size_info_32 uli_sizes[7] = +{ + {256, 65536, 6, 10}, + {128, 32768, 5, 9}, + {64, 16384, 4, 8}, + {32, 8192, 3, 7}, + {16, 4096, 2, 6}, + {8, 2048, 1, 4}, + {4, 1024, 0, 3} +}; +static int __devinit uli_agp_init(struct pci_dev *pdev) +{ + u32 httfea,baseaddr,enuscr; + struct pci_dev *dev1; + int i; + unsigned size = amd64_fetch_size(); + printk(KERN_INFO "Setting up ULi AGP. \n"); + dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0)); + if (dev1 == NULL) { + printk(KERN_INFO PFX "Detected a ULi chipset, " + "but could not fine the secondary device.\n"); + return -ENODEV; + } + + for (i = 0; i < ARRAY_SIZE(uli_sizes); i++) + if (uli_sizes[i].size == size) + break; + + if (i == ARRAY_SIZE(uli_sizes)) { + printk(KERN_INFO PFX "No ULi size found for %d\n", size); + return -ENODEV; + } + + /* shadow x86-64 registers into ULi registers */ + pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &httfea); + + /* if x86-64 aperture base is beyond 4G, exit here */ + if ((httfea & 0x7fff) >> (32 - 25)) + return -ENODEV; + + httfea = (httfea& 0x7fff) << 25; + + pci_read_config_dword(pdev, ULI_X86_64_BASE_ADDR, &baseaddr); + baseaddr&= ~PCI_BASE_ADDRESS_MEM_MASK; + baseaddr|= httfea; + pci_write_config_dword(pdev, ULI_X86_64_BASE_ADDR, baseaddr); + + enuscr= httfea+ (size * 1024 * 1024) - 1; + pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea); + pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr); + return 0; +} + + static struct aper_size_info_32 nforce3_sizes[5] = { {512, 131072, 7, 0x00000000 }, @@ -513,6 +574,14 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, } } + if (pdev->vendor == PCI_VENDOR_ID_AL) { + int ret = uli_agp_init(pdev); + if (ret) { + agp_put_bridge(bridge); + return ret; + } + } + pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); } @@ -536,6 +605,15 @@ static struct pci_device_id agp_amd64_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, + /* ULi M1689 */ + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_AL, + .device = PCI_DEVICE_ID_AL_M1689, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, /* VIA K8T800Pro */ { .class = (PCI_CLASS_BRIDGE_HOST << 8), @@ -581,7 +659,6 @@ static struct pci_device_id agp_amd64_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, - /* NForce3 */ { .class = (PCI_CLASS_BRIDGE_HOST << 8), @@ -625,6 +702,11 @@ static struct pci_driver agp_amd64_pci_driver = { int __init agp_amd64_init(void) { int err = 0; + static struct pci_device_id amd64nb[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) }, + { }, + }; + if (agp_off) return -EINVAL; if (pci_module_init(&agp_amd64_pci_driver) > 0) { @@ -640,13 +722,13 @@ int __init agp_amd64_init(void) } /* First check that we have at least one AMD64 NB */ - if (!pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL)) + if (!pci_dev_present(amd64nb)) return -ENODEV; /* Look for any AGP bridge */ dev = NULL; err = -ENODEV; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev))) { + for_each_pci_dev(dev) { if (!pci_find_capability(dev, PCI_CAP_ID_AGP)) continue; /* Only one bridge supported right now */ @@ -674,5 +756,5 @@ module_exit(agp_amd64_cleanup); #endif MODULE_AUTHOR("Dave Jones , Andi Kleen"); -MODULE_PARM(agp_try_unsupported, "1i"); +module_param(agp_try_unsupported, bool, 0); MODULE_LICENSE("GPL");