diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2010-11-06 06:18:58 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-23 15:14:47 -0500 |
commit | 4080775b60cc26044e7c4aba5e76e5041b0d7004 (patch) | |
tree | 46ee73a35bb1c99ff7e075e1c9b441faad98dc94 /drivers/char | |
parent | 7c2e6fdf452cddeff6a8ee5156edba39e53246fc (diff) |
intel-gtt: export api for drm/i915
Just some minor shuffling to get rid of any agp traces in the
exported functions.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 120 |
1 files changed, 68 insertions, 52 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 1603e4f8ae73..5a2b7360f5be 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -87,41 +87,29 @@ static struct _intel_private { | |||
87 | #define IS_IRONLAKE intel_private.driver->is_ironlake | 87 | #define IS_IRONLAKE intel_private.driver->is_ironlake |
88 | #define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable | 88 | #define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable |
89 | 89 | ||
90 | static void intel_agp_free_sglist(struct agp_memory *mem) | 90 | int intel_gtt_map_memory(struct page **pages, unsigned int num_entries, |
91 | { | 91 | struct scatterlist **sg_list, int *num_sg) |
92 | struct sg_table st; | ||
93 | |||
94 | st.sgl = mem->sg_list; | ||
95 | st.orig_nents = st.nents = mem->page_count; | ||
96 | |||
97 | sg_free_table(&st); | ||
98 | |||
99 | mem->sg_list = NULL; | ||
100 | mem->num_sg = 0; | ||
101 | } | ||
102 | |||
103 | static int intel_agp_map_memory(struct agp_memory *mem) | ||
104 | { | 92 | { |
105 | struct sg_table st; | 93 | struct sg_table st; |
106 | struct scatterlist *sg; | 94 | struct scatterlist *sg; |
107 | int i; | 95 | int i; |
108 | 96 | ||
109 | if (mem->sg_list) | 97 | if (*sg_list) |
110 | return 0; /* already mapped (for e.g. resume */ | 98 | return 0; /* already mapped (for e.g. resume */ |
111 | 99 | ||
112 | DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); | 100 | DBG("try mapping %lu pages\n", (unsigned long)num_entries); |
113 | 101 | ||
114 | if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) | 102 | if (sg_alloc_table(&st, num_entries, GFP_KERNEL)) |
115 | goto err; | 103 | goto err; |
116 | 104 | ||
117 | mem->sg_list = sg = st.sgl; | 105 | *sg_list = sg = st.sgl; |
118 | 106 | ||
119 | for (i = 0 ; i < mem->page_count; i++, sg = sg_next(sg)) | 107 | for (i = 0 ; i < num_entries; i++, sg = sg_next(sg)) |
120 | sg_set_page(sg, mem->pages[i], PAGE_SIZE, 0); | 108 | sg_set_page(sg, pages[i], PAGE_SIZE, 0); |
121 | 109 | ||
122 | mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list, | 110 | *num_sg = pci_map_sg(intel_private.pcidev, *sg_list, |
123 | mem->page_count, PCI_DMA_BIDIRECTIONAL); | 111 | num_entries, PCI_DMA_BIDIRECTIONAL); |
124 | if (unlikely(!mem->num_sg)) | 112 | if (unlikely(!*num_sg)) |
125 | goto err; | 113 | goto err; |
126 | 114 | ||
127 | return 0; | 115 | return 0; |
@@ -130,15 +118,22 @@ err: | |||
130 | sg_free_table(&st); | 118 | sg_free_table(&st); |
131 | return -ENOMEM; | 119 | return -ENOMEM; |
132 | } | 120 | } |
121 | EXPORT_SYMBOL(intel_gtt_map_memory); | ||
133 | 122 | ||
134 | static void intel_agp_unmap_memory(struct agp_memory *mem) | 123 | void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg) |
135 | { | 124 | { |
125 | struct sg_table st; | ||
136 | DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count); | 126 | DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count); |
137 | 127 | ||
138 | pci_unmap_sg(intel_private.pcidev, mem->sg_list, | 128 | pci_unmap_sg(intel_private.pcidev, sg_list, |
139 | mem->page_count, PCI_DMA_BIDIRECTIONAL); | 129 | num_sg, PCI_DMA_BIDIRECTIONAL); |
140 | intel_agp_free_sglist(mem); | 130 | |
131 | st.sgl = sg_list; | ||
132 | st.orig_nents = st.nents = num_sg; | ||
133 | |||
134 | sg_free_table(&st); | ||
141 | } | 135 | } |
136 | EXPORT_SYMBOL(intel_gtt_unmap_memory); | ||
142 | 137 | ||
143 | static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) | 138 | static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) |
144 | { | 139 | { |
@@ -307,7 +302,7 @@ static int intel_gtt_setup_scratch_page(void) | |||
307 | get_page(page); | 302 | get_page(page); |
308 | set_pages_uc(page, 1); | 303 | set_pages_uc(page, 1); |
309 | 304 | ||
310 | if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) { | 305 | if (intel_private.base.needs_dmar) { |
311 | dma_addr = pci_map_page(intel_private.pcidev, page, 0, | 306 | dma_addr = pci_map_page(intel_private.pcidev, page, 0, |
312 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 307 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
313 | if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) | 308 | if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) |
@@ -699,6 +694,8 @@ static int intel_gtt_init(void) | |||
699 | return ret; | 694 | return ret; |
700 | } | 695 | } |
701 | 696 | ||
697 | intel_private.base.needs_dmar = USE_PCI_DMA_API && INTEL_GTT_GEN > 2; | ||
698 | |||
702 | return 0; | 699 | return 0; |
703 | } | 700 | } |
704 | 701 | ||
@@ -892,10 +889,10 @@ static bool i830_check_flags(unsigned int flags) | |||
892 | return false; | 889 | return false; |
893 | } | 890 | } |
894 | 891 | ||
895 | static void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, | 892 | void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, |
896 | unsigned int sg_len, | 893 | unsigned int sg_len, |
897 | unsigned int pg_start, | 894 | unsigned int pg_start, |
898 | unsigned int flags) | 895 | unsigned int flags) |
899 | { | 896 | { |
900 | struct scatterlist *sg; | 897 | struct scatterlist *sg; |
901 | unsigned int len, m; | 898 | unsigned int len, m; |
@@ -916,11 +913,25 @@ static void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, | |||
916 | } | 913 | } |
917 | readl(intel_private.gtt+j-1); | 914 | readl(intel_private.gtt+j-1); |
918 | } | 915 | } |
916 | EXPORT_SYMBOL(intel_gtt_insert_sg_entries); | ||
917 | |||
918 | void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, | ||
919 | struct page **pages, unsigned int flags) | ||
920 | { | ||
921 | int i, j; | ||
922 | |||
923 | for (i = 0, j = first_entry; i < num_entries; i++, j++) { | ||
924 | dma_addr_t addr = page_to_phys(pages[i]); | ||
925 | intel_private.driver->write_entry(addr, | ||
926 | j, flags); | ||
927 | } | ||
928 | readl(intel_private.gtt+j-1); | ||
929 | } | ||
930 | EXPORT_SYMBOL(intel_gtt_insert_pages); | ||
919 | 931 | ||
920 | static int intel_fake_agp_insert_entries(struct agp_memory *mem, | 932 | static int intel_fake_agp_insert_entries(struct agp_memory *mem, |
921 | off_t pg_start, int type) | 933 | off_t pg_start, int type) |
922 | { | 934 | { |
923 | int i, j; | ||
924 | int ret = -EINVAL; | 935 | int ret = -EINVAL; |
925 | 936 | ||
926 | if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY) | 937 | if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY) |
@@ -941,21 +952,17 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem, | |||
941 | if (!mem->is_flushed) | 952 | if (!mem->is_flushed) |
942 | global_cache_flush(); | 953 | global_cache_flush(); |
943 | 954 | ||
944 | if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) { | 955 | if (intel_private.base.needs_dmar) { |
945 | ret = intel_agp_map_memory(mem); | 956 | ret = intel_gtt_map_memory(mem->pages, mem->page_count, |
957 | &mem->sg_list, &mem->num_sg); | ||
946 | if (ret != 0) | 958 | if (ret != 0) |
947 | return ret; | 959 | return ret; |
948 | 960 | ||
949 | intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg, | 961 | intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg, |
950 | pg_start, type); | 962 | pg_start, type); |
951 | } else { | 963 | } else |
952 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 964 | intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages, |
953 | dma_addr_t addr = page_to_phys(mem->pages[i]); | 965 | type); |
954 | intel_private.driver->write_entry(addr, | ||
955 | j, type); | ||
956 | } | ||
957 | readl(intel_private.gtt+j-1); | ||
958 | } | ||
959 | 966 | ||
960 | out: | 967 | out: |
961 | ret = 0; | 968 | ret = 0; |
@@ -964,22 +971,31 @@ out_err: | |||
964 | return ret; | 971 | return ret; |
965 | } | 972 | } |
966 | 973 | ||
974 | void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) | ||
975 | { | ||
976 | unsigned int i; | ||
977 | |||
978 | for (i = first_entry; i < (first_entry + num_entries); i++) { | ||
979 | intel_private.driver->write_entry(intel_private.scratch_page_dma, | ||
980 | i, 0); | ||
981 | } | ||
982 | readl(intel_private.gtt+i-1); | ||
983 | } | ||
984 | EXPORT_SYMBOL(intel_gtt_clear_range); | ||
985 | |||
967 | static int intel_fake_agp_remove_entries(struct agp_memory *mem, | 986 | static int intel_fake_agp_remove_entries(struct agp_memory *mem, |
968 | off_t pg_start, int type) | 987 | off_t pg_start, int type) |
969 | { | 988 | { |
970 | int i; | ||
971 | |||
972 | if (mem->page_count == 0) | 989 | if (mem->page_count == 0) |
973 | return 0; | 990 | return 0; |
974 | 991 | ||
975 | if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) | 992 | if (intel_private.base.needs_dmar) { |
976 | intel_agp_unmap_memory(mem); | 993 | intel_gtt_unmap_memory(mem->sg_list, mem->num_sg); |
977 | 994 | mem->sg_list = NULL; | |
978 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 995 | mem->num_sg = 0; |
979 | intel_private.driver->write_entry(intel_private.scratch_page_dma, | ||
980 | i, 0); | ||
981 | } | 996 | } |
982 | readl(intel_private.gtt+i-1); | 997 | |
998 | intel_gtt_clear_range(pg_start, mem->page_count); | ||
983 | 999 | ||
984 | return 0; | 1000 | return 0; |
985 | } | 1001 | } |