diff options
-rw-r--r-- | arch/x86/pci/i386.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 102 |
2 files changed, 103 insertions, 1 deletions
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 42ba0e2da1a0..103b9dff1213 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -72,7 +72,7 @@ pcibios_align_resource(void *data, struct resource *res, | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | } | 74 | } |
75 | 75 | EXPORT_SYMBOL(pcibios_align_resource); | |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * Handle resources of PCI devices. If the world were perfect, we could | 78 | * Handle resources of PCI devices. If the world were perfect, we could |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 189efb6ef970..4d062fc3e825 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -71,9 +71,11 @@ extern int agp_memory_reserved; | |||
71 | #define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) | 71 | #define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) |
72 | #define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) | 72 | #define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) |
73 | #define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) | 73 | #define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) |
74 | #define I915_IFPADDR 0x60 | ||
74 | 75 | ||
75 | /* Intel 965G registers */ | 76 | /* Intel 965G registers */ |
76 | #define I965_MSAC 0x62 | 77 | #define I965_MSAC 0x62 |
78 | #define I965_IFPADDR 0x70 | ||
77 | 79 | ||
78 | /* Intel 7505 registers */ | 80 | /* Intel 7505 registers */ |
79 | #define INTEL_I7505_APSIZE 0x74 | 81 | #define INTEL_I7505_APSIZE 0x74 |
@@ -115,6 +117,8 @@ static struct _intel_private { | |||
115 | * popup and for the GTT. | 117 | * popup and for the GTT. |
116 | */ | 118 | */ |
117 | int gtt_entries; /* i830+ */ | 119 | int gtt_entries; /* i830+ */ |
120 | void __iomem *flush_page; | ||
121 | struct resource ifp_resource; | ||
118 | } intel_private; | 122 | } intel_private; |
119 | 123 | ||
120 | static int intel_i810_fetch_size(void) | 124 | static int intel_i810_fetch_size(void) |
@@ -768,6 +772,73 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) | |||
768 | return NULL; | 772 | return NULL; |
769 | } | 773 | } |
770 | 774 | ||
775 | static int intel_alloc_chipset_flush_resource(void) | ||
776 | { | ||
777 | int ret; | ||
778 | ret = pci_bus_alloc_resource(agp_bridge->dev->bus, &intel_private.ifp_resource, PAGE_SIZE, | ||
779 | PAGE_SIZE, PCIBIOS_MIN_MEM, 0, | ||
780 | pcibios_align_resource, agp_bridge->dev); | ||
781 | if (ret != 0) | ||
782 | return ret; | ||
783 | |||
784 | printk("intel priv bus start %08lx\n", intel_private.ifp_resource.start); | ||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | static void intel_i915_setup_chipset_flush(void) | ||
789 | { | ||
790 | int ret; | ||
791 | u32 temp; | ||
792 | |||
793 | pci_read_config_dword(agp_bridge->dev, I915_IFPADDR, &temp); | ||
794 | if (!(temp & 0x1)) { | ||
795 | intel_alloc_chipset_flush_resource(); | ||
796 | |||
797 | pci_write_config_dword(agp_bridge->dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | ||
798 | } else { | ||
799 | temp &= ~1; | ||
800 | |||
801 | intel_private.ifp_resource.start = temp; | ||
802 | intel_private.ifp_resource.end = temp + PAGE_SIZE; | ||
803 | ret = request_resource(&iomem_resource, &intel_private.ifp_resource); | ||
804 | if (ret) { | ||
805 | intel_private.ifp_resource.start = 0; | ||
806 | printk("Failed inserting resource into tree\n"); | ||
807 | } | ||
808 | } | ||
809 | } | ||
810 | |||
811 | static void intel_i965_g33_setup_chipset_flush(void) | ||
812 | { | ||
813 | u32 temp_hi, temp_lo; | ||
814 | int ret; | ||
815 | |||
816 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR + 4, &temp_hi); | ||
817 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR, &temp_lo); | ||
818 | |||
819 | if (!(temp_lo & 0x1)) { | ||
820 | |||
821 | intel_alloc_chipset_flush_resource(); | ||
822 | |||
823 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR + 4, (intel_private.ifp_resource.start >> 32)); | ||
824 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | ||
825 | intel_private.flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); | ||
826 | } else { | ||
827 | u64 l64; | ||
828 | |||
829 | temp_lo &= ~0x1; | ||
830 | l64 = ((u64)temp_hi << 32) | temp_lo; | ||
831 | |||
832 | intel_private.ifp_resource.start = l64; | ||
833 | intel_private.ifp_resource.end = l64 + PAGE_SIZE; | ||
834 | ret = request_resource(&iomem_resource, &intel_private.ifp_resource); | ||
835 | if (!ret) { | ||
836 | intel_private.ifp_resource.start = 0; | ||
837 | printk("Failed inserting resource into tree\n"); | ||
838 | } | ||
839 | } | ||
840 | } | ||
841 | |||
771 | static int intel_i915_configure(void) | 842 | static int intel_i915_configure(void) |
772 | { | 843 | { |
773 | struct aper_size_info_fixed *current_size; | 844 | struct aper_size_info_fixed *current_size; |
@@ -796,15 +867,43 @@ static int intel_i915_configure(void) | |||
796 | } | 867 | } |
797 | 868 | ||
798 | global_cache_flush(); | 869 | global_cache_flush(); |
870 | |||
871 | /* setup a resource for this object */ | ||
872 | memset(&intel_private.ifp_resource, 0, sizeof(intel_private.ifp_resource)); | ||
873 | |||
874 | intel_private.ifp_resource.name = "Intel Flush Page"; | ||
875 | intel_private.ifp_resource.flags = IORESOURCE_MEM; | ||
876 | |||
877 | /* Setup chipset flush for 915 */ | ||
878 | if (IS_I965 || IS_G33) { | ||
879 | intel_i965_g33_setup_chipset_flush(); | ||
880 | } else { | ||
881 | intel_i915_setup_chipset_flush(); | ||
882 | } | ||
883 | |||
884 | if (intel_private.ifp_resource.start) { | ||
885 | intel_private.flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); | ||
886 | if (!intel_private.flush_page) | ||
887 | printk("unable to ioremap flush page - no chipset flushing"); | ||
888 | } | ||
889 | |||
799 | return 0; | 890 | return 0; |
800 | } | 891 | } |
801 | 892 | ||
802 | static void intel_i915_cleanup(void) | 893 | static void intel_i915_cleanup(void) |
803 | { | 894 | { |
895 | if (intel_private.flush_page) | ||
896 | iounmap(intel_private.flush_page); | ||
804 | iounmap(intel_private.gtt); | 897 | iounmap(intel_private.gtt); |
805 | iounmap(intel_private.registers); | 898 | iounmap(intel_private.registers); |
806 | } | 899 | } |
807 | 900 | ||
901 | static void intel_i915_chipset_flush(struct agp_bridge_data *bridge) | ||
902 | { | ||
903 | if (intel_private.flush_page) | ||
904 | writel(1, intel_private.flush_page); | ||
905 | } | ||
906 | |||
808 | static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start, | 907 | static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start, |
809 | int type) | 908 | int type) |
810 | { | 909 | { |
@@ -1721,6 +1820,7 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
1721 | .agp_alloc_page = agp_generic_alloc_page, | 1820 | .agp_alloc_page = agp_generic_alloc_page, |
1722 | .agp_destroy_page = agp_generic_destroy_page, | 1821 | .agp_destroy_page = agp_generic_destroy_page, |
1723 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1822 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1823 | .chipset_flush = intel_i915_chipset_flush, | ||
1724 | }; | 1824 | }; |
1725 | 1825 | ||
1726 | static const struct agp_bridge_driver intel_i965_driver = { | 1826 | static const struct agp_bridge_driver intel_i965_driver = { |
@@ -1746,6 +1846,7 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
1746 | .agp_alloc_page = agp_generic_alloc_page, | 1846 | .agp_alloc_page = agp_generic_alloc_page, |
1747 | .agp_destroy_page = agp_generic_destroy_page, | 1847 | .agp_destroy_page = agp_generic_destroy_page, |
1748 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1848 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1849 | .chipset_flush = intel_i915_chipset_flush, | ||
1749 | }; | 1850 | }; |
1750 | 1851 | ||
1751 | static const struct agp_bridge_driver intel_7505_driver = { | 1852 | static const struct agp_bridge_driver intel_7505_driver = { |
@@ -1795,6 +1896,7 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
1795 | .agp_alloc_page = agp_generic_alloc_page, | 1896 | .agp_alloc_page = agp_generic_alloc_page, |
1796 | .agp_destroy_page = agp_generic_destroy_page, | 1897 | .agp_destroy_page = agp_generic_destroy_page, |
1797 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1898 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1899 | .chipset_flush = intel_i915_chipset_flush, | ||
1798 | }; | 1900 | }; |
1799 | 1901 | ||
1800 | static int find_gmch(u16 device) | 1902 | static int find_gmch(u16 device) |