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.c95
1 files changed, 69 insertions, 26 deletions
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index aa8ec928caa8..c3fe78406d18 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -104,7 +104,6 @@ static unsigned long alloc_iommu(struct device *dev, int size)
104 size, base_index, boundary_size, 0); 104 size, base_index, boundary_size, 0);
105 } 105 }
106 if (offset != -1) { 106 if (offset != -1) {
107 set_bit_string(iommu_gart_bitmap, offset, size);
108 next_bit = offset+size; 107 next_bit = offset+size;
109 if (next_bit >= iommu_pages) { 108 if (next_bit >= iommu_pages) {
110 next_bit = 0; 109 next_bit = 0;
@@ -534,8 +533,8 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
534 unsigned aper_size = 0, aper_base_32, aper_order; 533 unsigned aper_size = 0, aper_base_32, aper_order;
535 u64 aper_base; 534 u64 aper_base;
536 535
537 pci_read_config_dword(dev, 0x94, &aper_base_32); 536 pci_read_config_dword(dev, AMD64_GARTAPERTUREBASE, &aper_base_32);
538 pci_read_config_dword(dev, 0x90, &aper_order); 537 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &aper_order);
539 aper_order = (aper_order >> 1) & 7; 538 aper_order = (aper_order >> 1) & 7;
540 539
541 aper_base = aper_base_32 & 0x7fff; 540 aper_base = aper_base_32 & 0x7fff;
@@ -549,14 +548,63 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
549 return aper_base; 548 return aper_base;
550} 549}
551 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
552static int gart_resume(struct sys_device *dev) 577static int gart_resume(struct sys_device *dev)
553{ 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
554 return 0; 602 return 0;
555} 603}
556 604
557static int gart_suspend(struct sys_device *dev, pm_message_t state) 605static int gart_suspend(struct sys_device *dev, pm_message_t state)
558{ 606{
559 return -EINVAL; 607 return 0;
560} 608}
561 609
562static struct sysdev_class gart_sysdev_class = { 610static struct sysdev_class gart_sysdev_class = {
@@ -582,6 +630,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
582 struct pci_dev *dev; 630 struct pci_dev *dev;
583 void *gatt; 631 void *gatt;
584 int i, error; 632 int i, error;
633 unsigned long start_pfn, end_pfn;
585 634
586 printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); 635 printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
587 aper_size = aper_base = info->aper_size = 0; 636 aper_size = aper_base = info->aper_size = 0;
@@ -614,31 +663,25 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
614 memset(gatt, 0, gatt_size); 663 memset(gatt, 0, gatt_size);
615 agp_gatt_table = gatt; 664 agp_gatt_table = gatt;
616 665
617 for (i = 0; i < num_k8_northbridges; i++) { 666 enable_gart_translations();
618 u32 gatt_reg;
619 u32 ctl;
620
621 dev = k8_northbridges[i];
622 gatt_reg = __pa(gatt) >> 12;
623 gatt_reg <<= 4;
624 pci_write_config_dword(dev, 0x98, gatt_reg);
625 pci_read_config_dword(dev, 0x90, &ctl);
626
627 ctl |= 1;
628 ctl &= ~((1<<4) | (1<<5));
629
630 pci_write_config_dword(dev, 0x90, ctl);
631 }
632 667
633 error = sysdev_class_register(&gart_sysdev_class); 668 error = sysdev_class_register(&gart_sysdev_class);
634 if (!error) 669 if (!error)
635 error = sysdev_register(&device_gart); 670 error = sysdev_register(&device_gart);
636 if (error) 671 if (error)
637 panic("Could not register gart_sysdev -- would corrupt data on next suspend"); 672 panic("Could not register gart_sysdev -- would corrupt data on next suspend");
673
638 flush_gart(); 674 flush_gart();
639 675
640 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",
641 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 }
642 return 0; 685 return 0;
643 686
644 nommu: 687 nommu:
@@ -677,11 +720,11 @@ void gart_iommu_shutdown(void)
677 u32 ctl; 720 u32 ctl;
678 721
679 dev = k8_northbridges[i]; 722 dev = k8_northbridges[i];
680 pci_read_config_dword(dev, 0x90, &ctl); 723 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl);
681 724
682 ctl &= ~1; 725 ctl &= ~GARTEN;
683 726
684 pci_write_config_dword(dev, 0x90, ctl); 727 pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl);
685 } 728 }
686} 729}
687 730
@@ -716,10 +759,10 @@ void __init gart_iommu_init(void)
716 return; 759 return;
717 760
718 if (no_iommu || 761 if (no_iommu ||
719 (!force_iommu && end_pfn <= MAX_DMA32_PFN) || 762 (!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
720 !gart_iommu_aperture || 763 !gart_iommu_aperture ||
721 (no_agp && init_k8_gatt(&info) < 0)) { 764 (no_agp && init_k8_gatt(&info) < 0)) {
722 if (end_pfn > MAX_DMA32_PFN) { 765 if (max_pfn > MAX_DMA32_PFN) {
723 printk(KERN_WARNING "More than 4GB of memory " 766 printk(KERN_WARNING "More than 4GB of memory "
724 "but GART IOMMU not available.\n" 767 "but GART IOMMU not available.\n"
725 KERN_WARNING "falling back to iommu=soft.\n"); 768 KERN_WARNING "falling back to iommu=soft.\n");
@@ -788,10 +831,10 @@ void __init gart_iommu_init(void)
788 wbinvd(); 831 wbinvd();
789 832
790 /* 833 /*
791 * Try to workaround a bug (thanks to BenH) 834 * Try to workaround a bug (thanks to BenH):
792 * Set unmapped entries to a scratch page instead of 0. 835 * Set unmapped entries to a scratch page instead of 0.
793 * 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
794 * then. 837 * then. (P2P bridge may be prefetching on DMA reads).
795 */ 838 */
796 scratch = get_zeroed_page(GFP_KERNEL); 839 scratch = get_zeroed_page(GFP_KERNEL);
797 if (!scratch) 840 if (!scratch)