diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-09 05:39:02 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 05:39:02 -0400 |
commit | d028203c0446c7f65ed2b22342a56f03c6c4a6c1 (patch) | |
tree | 6bd73a5c70b407491dc9d40ecb9e95b48233d004 /arch/x86/kernel/pci-gart_64.c | |
parent | f57e91682d141ea50d8c6d42cdc251b6256a3755 (diff) | |
parent | 183fe065652dbd64953afa9f389327e23e97967f (diff) |
Merge branch 'x86/core' into x86/unify-pci
Diffstat (limited to 'arch/x86/kernel/pci-gart_64.c')
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 87 |
1 files changed, 61 insertions, 26 deletions
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index aa8ec928caa8..d0d18db5d2a4 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 | ||
551 | static 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 | */ | ||
566 | static bool fix_up_north_bridges; | ||
567 | static u32 aperture_order; | ||
568 | static u32 aperture_alloc; | ||
569 | |||
570 | void 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 | |||
552 | static int gart_resume(struct sys_device *dev) | 577 | static 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 | ||
557 | static int gart_suspend(struct sys_device *dev, pm_message_t state) | 605 | static int gart_suspend(struct sys_device *dev, pm_message_t state) |
558 | { | 606 | { |
559 | return -EINVAL; | 607 | return 0; |
560 | } | 608 | } |
561 | 609 | ||
562 | static struct sysdev_class gart_sysdev_class = { | 610 | static struct sysdev_class gart_sysdev_class = { |
@@ -614,27 +662,14 @@ static __init int init_k8_gatt(struct agp_kern_info *info) | |||
614 | memset(gatt, 0, gatt_size); | 662 | memset(gatt, 0, gatt_size); |
615 | agp_gatt_table = gatt; | 663 | agp_gatt_table = gatt; |
616 | 664 | ||
617 | for (i = 0; i < num_k8_northbridges; i++) { | 665 | 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 | 666 | ||
633 | error = sysdev_class_register(&gart_sysdev_class); | 667 | error = sysdev_class_register(&gart_sysdev_class); |
634 | if (!error) | 668 | if (!error) |
635 | error = sysdev_register(&device_gart); | 669 | error = sysdev_register(&device_gart); |
636 | if (error) | 670 | if (error) |
637 | panic("Could not register gart_sysdev -- would corrupt data on next suspend"); | 671 | panic("Could not register gart_sysdev -- would corrupt data on next suspend"); |
672 | |||
638 | flush_gart(); | 673 | flush_gart(); |
639 | 674 | ||
640 | printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n", | 675 | printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n", |
@@ -677,11 +712,11 @@ void gart_iommu_shutdown(void) | |||
677 | u32 ctl; | 712 | u32 ctl; |
678 | 713 | ||
679 | dev = k8_northbridges[i]; | 714 | dev = k8_northbridges[i]; |
680 | pci_read_config_dword(dev, 0x90, &ctl); | 715 | pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl); |
681 | 716 | ||
682 | ctl &= ~1; | 717 | ctl &= ~GARTEN; |
683 | 718 | ||
684 | pci_write_config_dword(dev, 0x90, ctl); | 719 | pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl); |
685 | } | 720 | } |
686 | } | 721 | } |
687 | 722 | ||
@@ -716,10 +751,10 @@ void __init gart_iommu_init(void) | |||
716 | return; | 751 | return; |
717 | 752 | ||
718 | if (no_iommu || | 753 | if (no_iommu || |
719 | (!force_iommu && end_pfn <= MAX_DMA32_PFN) || | 754 | (!force_iommu && max_pfn <= MAX_DMA32_PFN) || |
720 | !gart_iommu_aperture || | 755 | !gart_iommu_aperture || |
721 | (no_agp && init_k8_gatt(&info) < 0)) { | 756 | (no_agp && init_k8_gatt(&info) < 0)) { |
722 | if (end_pfn > MAX_DMA32_PFN) { | 757 | if (max_pfn > MAX_DMA32_PFN) { |
723 | printk(KERN_WARNING "More than 4GB of memory " | 758 | printk(KERN_WARNING "More than 4GB of memory " |
724 | "but GART IOMMU not available.\n" | 759 | "but GART IOMMU not available.\n" |
725 | KERN_WARNING "falling back to iommu=soft.\n"); | 760 | KERN_WARNING "falling back to iommu=soft.\n"); |
@@ -788,10 +823,10 @@ void __init gart_iommu_init(void) | |||
788 | wbinvd(); | 823 | wbinvd(); |
789 | 824 | ||
790 | /* | 825 | /* |
791 | * Try to workaround a bug (thanks to BenH) | 826 | * Try to workaround a bug (thanks to BenH): |
792 | * Set unmapped entries to a scratch page instead of 0. | 827 | * Set unmapped entries to a scratch page instead of 0. |
793 | * Any prefetches that hit unmapped entries won't get an bus abort | 828 | * Any prefetches that hit unmapped entries won't get an bus abort |
794 | * then. | 829 | * then. (P2P bridge may be prefetching on DMA reads). |
795 | */ | 830 | */ |
796 | scratch = get_zeroed_page(GFP_KERNEL); | 831 | scratch = get_zeroed_page(GFP_KERNEL); |
797 | if (!scratch) | 832 | if (!scratch) |