aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/pci-gart_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/pci-gart_64.c')
-rw-r--r--arch/x86/kernel/pci-gart_64.c120
1 files changed, 96 insertions, 24 deletions
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index c07455d1695f..c3fe78406d18 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -26,6 +26,7 @@
26#include <linux/kdebug.h> 26#include <linux/kdebug.h>
27#include <linux/scatterlist.h> 27#include <linux/scatterlist.h>
28#include <linux/iommu-helper.h> 28#include <linux/iommu-helper.h>
29#include <linux/sysdev.h>
29#include <asm/atomic.h> 30#include <asm/atomic.h>
30#include <asm/io.h> 31#include <asm/io.h>
31#include <asm/mtrr.h> 32#include <asm/mtrr.h>
@@ -103,7 +104,6 @@ static unsigned long alloc_iommu(struct device *dev, int size)
103 size, base_index, boundary_size, 0); 104 size, base_index, boundary_size, 0);
104 } 105 }
105 if (offset != -1) { 106 if (offset != -1) {
106 set_bit_string(iommu_gart_bitmap, offset, size);
107 next_bit = offset+size; 107 next_bit = offset+size;
108 if (next_bit >= iommu_pages) { 108 if (next_bit >= iommu_pages) {
109 next_bit = 0; 109 next_bit = 0;
@@ -533,8 +533,8 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
533 unsigned aper_size = 0, aper_base_32, aper_order; 533 unsigned aper_size = 0, aper_base_32, aper_order;
534 u64 aper_base; 534 u64 aper_base;
535 535
536 pci_read_config_dword(dev, 0x94, &aper_base_32); 536 pci_read_config_dword(dev, AMD64_GARTAPERTUREBASE, &aper_base_32);
537 pci_read_config_dword(dev, 0x90, &aper_order); 537 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &aper_order);
538 aper_order = (aper_order >> 1) & 7; 538 aper_order = (aper_order >> 1) & 7;
539 539
540 aper_base = aper_base_32 & 0x7fff; 540 aper_base = aper_base_32 & 0x7fff;
@@ -548,6 +548,77 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
548 return aper_base; 548 return aper_base;
549} 549}
550 550
551static void enable_gart_translations(void)
552{
553 int i;
554
555 for (i = 0; i < num_k8_northbridges; i++) {
556 struct pci_dev *dev = k8_northbridges[i];
557
558 enable_gart_translation(dev, __pa(agp_gatt_table));
559 }
560}
561
562/*
563 * If fix_up_north_bridges is set, the north bridges have to be fixed up on
564 * resume in the same way as they are handled in gart_iommu_hole_init().
565 */
566static bool fix_up_north_bridges;
567static u32 aperture_order;
568static u32 aperture_alloc;
569
570void set_up_gart_resume(u32 aper_order, u32 aper_alloc)
571{
572 fix_up_north_bridges = true;
573 aperture_order = aper_order;
574 aperture_alloc = aper_alloc;
575}
576
577static int gart_resume(struct sys_device *dev)
578{
579 printk(KERN_INFO "PCI-DMA: Resuming GART IOMMU\n");
580
581 if (fix_up_north_bridges) {
582 int i;
583
584 printk(KERN_INFO "PCI-DMA: Restoring GART aperture settings\n");
585
586 for (i = 0; i < num_k8_northbridges; i++) {
587 struct pci_dev *dev = k8_northbridges[i];
588
589 /*
590 * Don't enable translations just yet. That is the next
591 * step. Restore the pre-suspend aperture settings.
592 */
593 pci_write_config_dword(dev, AMD64_GARTAPERTURECTL,
594 aperture_order << 1);
595 pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE,
596 aperture_alloc >> 25);
597 }
598 }
599
600 enable_gart_translations();
601
602 return 0;
603}
604
605static int gart_suspend(struct sys_device *dev, pm_message_t state)
606{
607 return 0;
608}
609
610static struct sysdev_class gart_sysdev_class = {
611 .name = "gart",
612 .suspend = gart_suspend,
613 .resume = gart_resume,
614
615};
616
617static struct sys_device device_gart = {
618 .id = 0,
619 .cls = &gart_sysdev_class,
620};
621
551/* 622/*
552 * Private Northbridge GATT initialization in case we cannot use the 623 * Private Northbridge GATT initialization in case we cannot use the
553 * AGP driver for some reason. 624 * AGP driver for some reason.
@@ -558,7 +629,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
558 unsigned aper_base, new_aper_base; 629 unsigned aper_base, new_aper_base;
559 struct pci_dev *dev; 630 struct pci_dev *dev;
560 void *gatt; 631 void *gatt;
561 int i; 632 int i, error;
633 unsigned long start_pfn, end_pfn;
562 634
563 printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); 635 printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
564 aper_size = aper_base = info->aper_size = 0; 636 aper_size = aper_base = info->aper_size = 0;
@@ -591,25 +663,25 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
591 memset(gatt, 0, gatt_size); 663 memset(gatt, 0, gatt_size);
592 agp_gatt_table = gatt; 664 agp_gatt_table = gatt;
593 665
594 for (i = 0; i < num_k8_northbridges; i++) { 666 enable_gart_translations();
595 u32 gatt_reg;
596 u32 ctl;
597 667
598 dev = k8_northbridges[i]; 668 error = sysdev_class_register(&gart_sysdev_class);
599 gatt_reg = __pa(gatt) >> 12; 669 if (!error)
600 gatt_reg <<= 4; 670 error = sysdev_register(&device_gart);
601 pci_write_config_dword(dev, 0x98, gatt_reg); 671 if (error)
602 pci_read_config_dword(dev, 0x90, &ctl); 672 panic("Could not register gart_sysdev -- would corrupt data on next suspend");
603
604 ctl |= 1;
605 ctl &= ~((1<<4) | (1<<5));
606 673
607 pci_write_config_dword(dev, 0x90, ctl);
608 }
609 flush_gart(); 674 flush_gart();
610 675
611 printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n", 676 printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
612 aper_base, aper_size>>10); 677 aper_base, aper_size>>10);
678
679 /* need to map that range */
680 end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
681 if (end_pfn > max_low_pfn_mapped) {
682 start_pfn = (aper_base>>PAGE_SHIFT);
683 init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
684 }
613 return 0; 685 return 0;
614 686
615 nommu: 687 nommu:
@@ -648,11 +720,11 @@ void gart_iommu_shutdown(void)
648 u32 ctl; 720 u32 ctl;
649 721
650 dev = k8_northbridges[i]; 722 dev = k8_northbridges[i];
651 pci_read_config_dword(dev, 0x90, &ctl); 723 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl);
652 724
653 ctl &= ~1; 725 ctl &= ~GARTEN;
654 726
655 pci_write_config_dword(dev, 0x90, ctl); 727 pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl);
656 } 728 }
657} 729}
658 730
@@ -687,10 +759,10 @@ void __init gart_iommu_init(void)
687 return; 759 return;
688 760
689 if (no_iommu || 761 if (no_iommu ||
690 (!force_iommu && end_pfn <= MAX_DMA32_PFN) || 762 (!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
691 !gart_iommu_aperture || 763 !gart_iommu_aperture ||
692 (no_agp && init_k8_gatt(&info) < 0)) { 764 (no_agp && init_k8_gatt(&info) < 0)) {
693 if (end_pfn > MAX_DMA32_PFN) { 765 if (max_pfn > MAX_DMA32_PFN) {
694 printk(KERN_WARNING "More than 4GB of memory " 766 printk(KERN_WARNING "More than 4GB of memory "
695 "but GART IOMMU not available.\n" 767 "but GART IOMMU not available.\n"
696 KERN_WARNING "falling back to iommu=soft.\n"); 768 KERN_WARNING "falling back to iommu=soft.\n");
@@ -759,10 +831,10 @@ void __init gart_iommu_init(void)
759 wbinvd(); 831 wbinvd();
760 832
761 /* 833 /*
762 * Try to workaround a bug (thanks to BenH) 834 * Try to workaround a bug (thanks to BenH):
763 * Set unmapped entries to a scratch page instead of 0. 835 * Set unmapped entries to a scratch page instead of 0.
764 * Any prefetches that hit unmapped entries won't get an bus abort 836 * Any prefetches that hit unmapped entries won't get an bus abort
765 * then. 837 * then. (P2P bridge may be prefetching on DMA reads).
766 */ 838 */
767 scratch = get_zeroed_page(GFP_KERNEL); 839 scratch = get_zeroed_page(GFP_KERNEL);
768 if (!scratch) 840 if (!scratch)