aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/intel-gtt.c62
1 files changed, 30 insertions, 32 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 58e32f7c3229..e01f5eaaec82 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -84,40 +84,33 @@ static struct _intel_private {
84#define IS_IRONLAKE intel_private.driver->is_ironlake 84#define IS_IRONLAKE intel_private.driver->is_ironlake
85#define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable 85#define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable
86 86
87int intel_gtt_map_memory(struct page **pages, unsigned int num_entries, 87static int intel_gtt_map_memory(struct page **pages,
88 struct scatterlist **sg_list, int *num_sg) 88 unsigned int num_entries,
89 struct sg_table *st)
89{ 90{
90 struct sg_table st;
91 struct scatterlist *sg; 91 struct scatterlist *sg;
92 int i; 92 int i;
93 93
94 if (*sg_list)
95 return 0; /* already mapped (for e.g. resume */
96
97 DBG("try mapping %lu pages\n", (unsigned long)num_entries); 94 DBG("try mapping %lu pages\n", (unsigned long)num_entries);
98 95
99 if (sg_alloc_table(&st, num_entries, GFP_KERNEL)) 96 if (sg_alloc_table(st, num_entries, GFP_KERNEL))
100 goto err; 97 goto err;
101 98
102 *sg_list = sg = st.sgl; 99 for_each_sg(st->sgl, sg, num_entries, i)
103
104 for (i = 0 ; i < num_entries; i++, sg = sg_next(sg))
105 sg_set_page(sg, pages[i], PAGE_SIZE, 0); 100 sg_set_page(sg, pages[i], PAGE_SIZE, 0);
106 101
107 *num_sg = pci_map_sg(intel_private.pcidev, *sg_list, 102 if (!pci_map_sg(intel_private.pcidev,
108 num_entries, PCI_DMA_BIDIRECTIONAL); 103 st->sgl, st->nents, PCI_DMA_BIDIRECTIONAL))
109 if (unlikely(!*num_sg))
110 goto err; 104 goto err;
111 105
112 return 0; 106 return 0;
113 107
114err: 108err:
115 sg_free_table(&st); 109 sg_free_table(st);
116 return -ENOMEM; 110 return -ENOMEM;
117} 111}
118EXPORT_SYMBOL(intel_gtt_map_memory);
119 112
120void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg) 113static void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
121{ 114{
122 struct sg_table st; 115 struct sg_table st;
123 DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count); 116 DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count);
@@ -130,7 +123,6 @@ void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg)
130 123
131 sg_free_table(&st); 124 sg_free_table(&st);
132} 125}
133EXPORT_SYMBOL(intel_gtt_unmap_memory);
134 126
135static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) 127static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode)
136{ 128{
@@ -674,9 +666,14 @@ static int intel_gtt_init(void)
674 666
675 gtt_map_size = intel_private.base.gtt_total_entries * 4; 667 gtt_map_size = intel_private.base.gtt_total_entries * 4;
676 668
677 intel_private.gtt = ioremap(intel_private.gtt_bus_addr, 669 intel_private.gtt = NULL;
678 gtt_map_size); 670 if (INTEL_GTT_GEN < 6)
679 if (!intel_private.gtt) { 671 intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr,
672 gtt_map_size);
673 if (intel_private.gtt == NULL)
674 intel_private.gtt = ioremap(intel_private.gtt_bus_addr,
675 gtt_map_size);
676 if (intel_private.gtt == NULL) {
680 intel_private.driver->cleanup(); 677 intel_private.driver->cleanup();
681 iounmap(intel_private.registers); 678 iounmap(intel_private.registers);
682 return -ENOMEM; 679 return -ENOMEM;
@@ -879,8 +876,7 @@ static bool i830_check_flags(unsigned int flags)
879 return false; 876 return false;
880} 877}
881 878
882void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, 879void intel_gtt_insert_sg_entries(struct sg_table *st,
883 unsigned int sg_len,
884 unsigned int pg_start, 880 unsigned int pg_start,
885 unsigned int flags) 881 unsigned int flags)
886{ 882{
@@ -892,12 +888,11 @@ void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
892 888
893 /* sg may merge pages, but we have to separate 889 /* sg may merge pages, but we have to separate
894 * per-page addr for GTT */ 890 * per-page addr for GTT */
895 for_each_sg(sg_list, sg, sg_len, i) { 891 for_each_sg(st->sgl, sg, st->nents, i) {
896 len = sg_dma_len(sg) >> PAGE_SHIFT; 892 len = sg_dma_len(sg) >> PAGE_SHIFT;
897 for (m = 0; m < len; m++) { 893 for (m = 0; m < len; m++) {
898 dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT); 894 dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
899 intel_private.driver->write_entry(addr, 895 intel_private.driver->write_entry(addr, j, flags);
900 j, flags);
901 j++; 896 j++;
902 } 897 }
903 } 898 }
@@ -905,8 +900,10 @@ void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
905} 900}
906EXPORT_SYMBOL(intel_gtt_insert_sg_entries); 901EXPORT_SYMBOL(intel_gtt_insert_sg_entries);
907 902
908void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, 903static void intel_gtt_insert_pages(unsigned int first_entry,
909 struct page **pages, unsigned int flags) 904 unsigned int num_entries,
905 struct page **pages,
906 unsigned int flags)
910{ 907{
911 int i, j; 908 int i, j;
912 909
@@ -917,7 +914,6 @@ void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries,
917 } 914 }
918 readl(intel_private.gtt+j-1); 915 readl(intel_private.gtt+j-1);
919} 916}
920EXPORT_SYMBOL(intel_gtt_insert_pages);
921 917
922static int intel_fake_agp_insert_entries(struct agp_memory *mem, 918static int intel_fake_agp_insert_entries(struct agp_memory *mem,
923 off_t pg_start, int type) 919 off_t pg_start, int type)
@@ -953,13 +949,15 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
953 global_cache_flush(); 949 global_cache_flush();
954 950
955 if (intel_private.base.needs_dmar) { 951 if (intel_private.base.needs_dmar) {
956 ret = intel_gtt_map_memory(mem->pages, mem->page_count, 952 struct sg_table st;
957 &mem->sg_list, &mem->num_sg); 953
954 ret = intel_gtt_map_memory(mem->pages, mem->page_count, &st);
958 if (ret != 0) 955 if (ret != 0)
959 return ret; 956 return ret;
960 957
961 intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg, 958 intel_gtt_insert_sg_entries(&st, pg_start, type);
962 pg_start, type); 959 mem->sg_list = st.sgl;
960 mem->num_sg = st.nents;
963 } else 961 } else
964 intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages, 962 intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages,
965 type); 963 type);