diff -Naur linux-source-2.6.24/arch/x86/kernel/aperture_64.c linux-new/arch/x86/kernel/aperture_64.c --- linux-source-2.6.24/arch/x86/kernel/aperture_64.c 2008-07-12 04:07:15.000000000 +0530 +++ linux-new/arch/x86/kernel/aperture_64.c 2008-08-11 19:28:32.000000000 +0530 @@ -207,6 +207,28 @@ return 0; } +u32 fix_aper_enabled, fix_aper_order, fix_aper_alloc; + +void fix_up_north_bridges(void) +{ + int num; + + if (!fix_aper_enabled) + return; + + /* Fix up the north bridges */ + for (num = 24; num < 32; num++) { + if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) + continue; + + /* Don't enable translation yet. That is done later. + Assume this BIOS didn't initialise the GART so + just overwrite all previous bits */ + write_pci_config(0, num, 3, 0x90, fix_aper_order<<1); + write_pci_config(0, num, 3, 0x94, fix_aper_alloc>>25); + } +} + void __init gart_iommu_hole_init(void) { int fix, num; @@ -288,15 +310,8 @@ return; } - /* Fix up the north bridges */ - for (num = 24; num < 32; num++) { - if (!early_is_k8_nb(read_pci_config(0, num, 3, 0x00))) - continue; - - /* Don't enable translation yet. That is done later. - Assume this BIOS didn't initialise the GART so - just overwrite all previous bits */ - write_pci_config(0, num, 3, 0x90, aper_order<<1); - write_pci_config(0, num, 3, 0x94, aper_alloc>>25); - } + fix_aper_enabled = 1; + fix_aper_order = aper_order; + fix_aper_alloc = aper_alloc; + fix_up_north_bridges(); } diff -Naur linux-source-2.6.24/arch/x86/kernel/k8.c linux-new/arch/x86/kernel/k8.c --- linux-source-2.6.24/arch/x86/kernel/k8.c 2008-02-11 11:21:11.000000000 +0530 +++ linux-new/arch/x86/kernel/k8.c 2008-08-11 19:29:47.000000000 +0530 @@ -76,7 +76,7 @@ /* Ignores subdevice/subvendor but as far as I can figure out they're useless anyways */ -int __init early_is_k8_nb(u32 device) +int early_is_k8_nb(u32 device) { struct pci_device_id *id; u32 vendor = device & 0xffff; diff -Naur linux-source-2.6.24/arch/x86/kernel/pci-gart_64.c linux-new/arch/x86/kernel/pci-gart_64.c --- linux-source-2.6.24/arch/x86/kernel/pci-gart_64.c 2008-02-11 11:21:11.000000000 +0530 +++ linux-new/arch/x86/kernel/pci-gart_64.c 2008-08-11 19:44:03.000000000 +0530 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +75,7 @@ /* backdoor interface to AGP driver */ AGPEXTERN int agp_memory_reserved; -AGPEXTERN __u32 *agp_gatt_table; +AGPEXTERN u32 *agp_gatt_table; static unsigned long next_bit; /* protected by iommu_bitmap_lock */ static int need_flush; /* global flush state. set for each gart wrap */ @@ -492,6 +493,52 @@ return aper_base; } +static void enable_gart_translations(void) +{ + int i; + struct pci_dev *dev; + + for (i = 0; i < num_k8_northbridges; i++) { + u32 ctl; + u32 gatt_reg; + + dev = k8_northbridges[i]; + gatt_reg = __pa(agp_gatt_table) >> 12; + gatt_reg <<= 4; + pci_write_config_dword(dev, 0x98, gatt_reg); + pci_read_config_dword(dev, 0x90, &ctl); + + ctl |= 1; + ctl &= ~((1<<4) | (1<<5)); + + pci_write_config_dword(dev, 0x90, ctl); + } +} + +static int gart_resume(struct sys_device *dev) +{ + fix_up_north_bridges(); + enable_gart_translations(); + + return 0; +} + +static int gart_suspend(struct sys_device *dev, pm_message_t state) +{ + return 0; +} + +static struct sysdev_class gart_sysdev_class = { + set_kset_name("gart"), + .suspend = gart_suspend, + .resume = gart_resume, +}; + +static struct sys_device device_gart = { + .id = 0, + .cls = &gart_sysdev_class, +}; + /* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason. @@ -502,7 +549,7 @@ void *gatt; unsigned aper_base, new_aper_base; unsigned aper_size, gatt_size, new_aper_size; - int i; + int i, error; printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); aper_size = aper_base = info->aper_size = 0; @@ -536,21 +583,14 @@ memset(gatt, 0, gatt_size); agp_gatt_table = gatt; - for (i = 0; i < num_k8_northbridges; i++) { - u32 ctl; - u32 gatt_reg; - - dev = k8_northbridges[i]; - gatt_reg = __pa(gatt) >> 12; - gatt_reg <<= 4; - pci_write_config_dword(dev, 0x98, gatt_reg); - pci_read_config_dword(dev, 0x90, &ctl); - - ctl |= 1; - ctl &= ~((1<<4) | (1<<5)); + enable_gart_translations(); + + error = sysdev_class_register(&gart_sysdev_class); + if (!error) + error = sysdev_register(&device_gart); + else + panic("Could not register gart_sysdev -- would corrupt data on next suspend"); - pci_write_config_dword(dev, 0x90, ctl); - } flush_gart(); printk("PCI-DMA: aperture base @ %x size %u KB\n",aper_base, aper_size>>10); diff -Naur linux-source-2.6.24/drivers/char/agp/generic.c linux-new/drivers/char/agp/generic.c --- linux-source-2.6.24/drivers/char/agp/generic.c 2008-02-11 11:21:11.000000000 +0530 +++ linux-new/drivers/char/agp/generic.c 2008-08-11 19:44:48.000000000 +0530 @@ -43,7 +43,7 @@ #include #include "agp.h" -__u32 *agp_gatt_table; +u32 *agp_gatt_table; int agp_memory_reserved; /* diff -Naur linux-source-2.6.24/include/asm-x86/k8.h linux-new/include/asm-x86/k8.h --- linux-source-2.6.24/include/asm-x86/k8.h 2008-02-11 11:21:11.000000000 +0530 +++ linux-new/include/asm-x86/k8.h 2008-08-11 19:46:29.000000000 +0530 @@ -10,5 +10,6 @@ extern int num_k8_northbridges; extern int cache_k8_northbridges(void); extern void k8_flush_garts(void); +extern void fix_up_north_bridges(void); #endif