Rev 5354 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5354 | Rev 6084 | ||
---|---|---|---|
Line 118... | Line 118... | ||
118 | #define IS_G33 intel_private.driver->is_g33 |
118 | #define IS_G33 intel_private.driver->is_g33 |
119 | #define IS_PINEVIEW intel_private.driver->is_pineview |
119 | #define IS_PINEVIEW intel_private.driver->is_pineview |
120 | #define IS_IRONLAKE intel_private.driver->is_ironlake |
120 | #define IS_IRONLAKE intel_private.driver->is_ironlake |
121 | #define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable |
121 | #define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable |
Line -... | Line 122... | ||
- | 122 | ||
- | 123 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
|
- | 124 | static int intel_gtt_map_memory(struct page **pages, |
|
- | 125 | unsigned int num_entries, |
|
- | 126 | struct sg_table *st) |
|
- | 127 | { |
|
- | 128 | struct scatterlist *sg; |
|
- | 129 | int i; |
|
- | 130 | ||
- | 131 | DBG("try mapping %lu pages\n", (unsigned long)num_entries); |
|
- | 132 | ||
- | 133 | if (sg_alloc_table(st, num_entries, GFP_KERNEL)) |
|
- | 134 | goto err; |
|
- | 135 | ||
- | 136 | for_each_sg(st->sgl, sg, num_entries, i) |
|
- | 137 | sg_set_page(sg, pages[i], PAGE_SIZE, 0); |
|
- | 138 | ||
- | 139 | if (!pci_map_sg(intel_private.pcidev, |
|
- | 140 | st->sgl, st->nents, PCI_DMA_BIDIRECTIONAL)) |
|
- | 141 | goto err; |
|
- | 142 | ||
- | 143 | return 0; |
|
- | 144 | ||
- | 145 | err: |
|
- | 146 | sg_free_table(st); |
|
- | 147 | return -ENOMEM; |
|
- | 148 | } |
|
- | 149 | ||
- | 150 | static void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg) |
|
- | 151 | { |
|
- | 152 | struct sg_table st; |
|
- | 153 | DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count); |
|
- | 154 | ||
- | 155 | pci_unmap_sg(intel_private.pcidev, sg_list, |
|
- | 156 | num_sg, PCI_DMA_BIDIRECTIONAL); |
|
- | 157 | ||
- | 158 | st.sgl = sg_list; |
|
- | 159 | st.orig_nents = st.nents = num_sg; |
|
- | 160 | ||
- | 161 | sg_free_table(&st); |
|
- | 162 | } |
|
- | 163 | ||
- | 164 | static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) |
|
- | 165 | { |
|
- | 166 | return; |
|
- | 167 | } |
|
- | 168 | ||
- | 169 | /* Exists to support ARGB cursors */ |
|
- | 170 | static struct page *i8xx_alloc_pages(void) |
|
- | 171 | { |
|
- | 172 | struct page *page; |
|
- | 173 | ||
- | 174 | page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2); |
|
- | 175 | if (page == NULL) |
|
- | 176 | return NULL; |
|
- | 177 | ||
- | 178 | if (set_pages_uc(page, 4) < 0) { |
|
- | 179 | set_pages_wb(page, 4); |
|
- | 180 | __free_pages(page, 2); |
|
- | 181 | return NULL; |
|
- | 182 | } |
|
- | 183 | atomic_inc(&agp_bridge->current_memory_agp); |
|
- | 184 | return page; |
|
- | 185 | } |
|
- | 186 | ||
- | 187 | static void i8xx_destroy_pages(struct page *page) |
|
- | 188 | { |
|
- | 189 | if (page == NULL) |
|
- | 190 | return; |
|
- | 191 | ||
- | 192 | set_pages_wb(page, 4); |
|
- | 193 | __free_pages(page, 2); |
|
- | 194 | atomic_dec(&agp_bridge->current_memory_agp); |
|
- | 195 | } |
|
- | 196 | #endif |
|
- | 197 | ||
- | 198 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
|
- | 199 | static int i810_insert_dcache_entries(struct agp_memory *mem, off_t pg_start, |
|
- | 200 | int type) |
|
- | 201 | { |
|
- | 202 | int i; |
|
- | 203 | ||
- | 204 | if ((pg_start + mem->page_count) |
|
- | 205 | > intel_private.num_dcache_entries) |
|
- | 206 | return -EINVAL; |
|
- | 207 | ||
- | 208 | if (!mem->is_flushed) |
|
- | 209 | global_cache_flush(); |
|
- | 210 | ||
- | 211 | for (i = pg_start; i < (pg_start + mem->page_count); i++) { |
|
- | 212 | dma_addr_t addr = i << PAGE_SHIFT; |
|
- | 213 | intel_private.driver->write_entry(addr, |
|
- | 214 | i, type); |
|
- | 215 | } |
|
- | 216 | wmb(); |
|
- | 217 | ||
- | 218 | return 0; |
|
- | 219 | } |
|
- | 220 | ||
- | 221 | /* |
|
- | 222 | * The i810/i830 requires a physical address to program its mouse |
|
- | 223 | * pointer into hardware. |
|
- | 224 | * However the Xserver still writes to it through the agp aperture. |
|
- | 225 | */ |
|
- | 226 | static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) |
|
- | 227 | { |
|
- | 228 | struct agp_memory *new; |
|
- | 229 | struct page *page; |
|
- | 230 | ||
- | 231 | switch (pg_count) { |
|
- | 232 | case 1: page = agp_bridge->driver->agp_alloc_page(agp_bridge); |
|
- | 233 | break; |
|
- | 234 | case 4: |
|
- | 235 | /* kludge to get 4 physical pages for ARGB cursor */ |
|
- | 236 | page = i8xx_alloc_pages(); |
|
- | 237 | break; |
|
- | 238 | default: |
|
- | 239 | return NULL; |
|
- | 240 | } |
|
- | 241 | ||
- | 242 | if (page == NULL) |
|
- | 243 | return NULL; |
|
- | 244 | ||
- | 245 | new = agp_create_memory(pg_count); |
|
- | 246 | if (new == NULL) |
|
- | 247 | return NULL; |
|
- | 248 | ||
- | 249 | new->pages[0] = page; |
|
- | 250 | if (pg_count == 4) { |
|
- | 251 | /* kludge to get 4 physical pages for ARGB cursor */ |
|
- | 252 | new->pages[1] = new->pages[0] + 1; |
|
- | 253 | new->pages[2] = new->pages[1] + 1; |
|
- | 254 | new->pages[3] = new->pages[2] + 1; |
|
- | 255 | } |
|
- | 256 | new->page_count = pg_count; |
|
- | 257 | new->num_scratch_pages = pg_count; |
|
- | 258 | new->type = AGP_PHYS_MEMORY; |
|
- | 259 | new->physical = page_to_phys(new->pages[0]); |
|
- | 260 | return new; |
|
- | 261 | } |
|
- | 262 | ||
- | 263 | static void intel_i810_free_by_type(struct agp_memory *curr) |
|
- | 264 | { |
|
- | 265 | agp_free_key(curr->key); |
|
- | 266 | if (curr->type == AGP_PHYS_MEMORY) { |
|
- | 267 | if (curr->page_count == 4) |
|
- | 268 | i8xx_destroy_pages(curr->pages[0]); |
|
- | 269 | else { |
|
- | 270 | agp_bridge->driver->agp_destroy_page(curr->pages[0], |
|
- | 271 | AGP_PAGE_DESTROY_UNMAP); |
|
- | 272 | agp_bridge->driver->agp_destroy_page(curr->pages[0], |
|
- | 273 | AGP_PAGE_DESTROY_FREE); |
|
- | 274 | } |
|
- | 275 | agp_free_page_array(curr); |
|
- | 276 | } |
|
- | 277 | kfree(curr); |
|
- | 278 | } |
|
- | 279 | #endif |
|
122 | 280 | ||
123 | static int intel_gtt_setup_scratch_page(void) |
281 | static int intel_gtt_setup_scratch_page(void) |
124 | { |
282 | { |
125 | struct page *page; |
283 | struct page *page; |
Line 371... | Line 529... | ||
371 | const unsigned short gpu_devid = intel_private.pcidev->device; |
529 | const unsigned short gpu_devid = intel_private.pcidev->device; |
Line 372... | Line 530... | ||
372 | 530 | ||
373 | /* Query intel_iommu to see if we need the workaround. Presumably that |
531 | /* Query intel_iommu to see if we need the workaround. Presumably that |
374 | * was loaded first. |
532 | * was loaded first. |
375 | */ |
533 | */ |
376 | if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || |
534 | if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG || |
377 | gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && |
535 | gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && |
378 | intel_iommu_gfx_mapped) |
536 | intel_iommu_gfx_mapped) |
379 | return 1; |
537 | return 1; |
380 | #endif |
538 | #endif |
Line 454... | Line 612... | ||
454 | 612 | ||
455 | intel_private.gma_bus_addr = pci_bus_address(intel_private.pcidev, bar); |
613 | intel_private.gma_bus_addr = pci_bus_address(intel_private.pcidev, bar); |
456 | return 0; |
614 | return 0; |
Line -... | Line 615... | ||
- | 615 | } |
|
- | 616 | ||
- | 617 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
|
- | 618 | static int intel_fake_agp_fetch_size(void) |
|
- | 619 | { |
|
- | 620 | int num_sizes = ARRAY_SIZE(intel_fake_agp_sizes); |
|
- | 621 | unsigned int aper_size; |
|
- | 622 | int i; |
|
- | 623 | ||
- | 624 | aper_size = (intel_private.gtt_mappable_entries << PAGE_SHIFT) / MB(1); |
|
- | 625 | ||
- | 626 | for (i = 0; i < num_sizes; i++) { |
|
- | 627 | if (aper_size == intel_fake_agp_sizes[i].size) { |
|
- | 628 | agp_bridge->current_size = |
|
- | 629 | (void *) (intel_fake_agp_sizes + i); |
|
- | 630 | return aper_size; |
|
- | 631 | } |
|
- | 632 | } |
|
- | 633 | ||
- | 634 | return 0; |
|
Line 457... | Line 635... | ||
457 | } |
635 | } |
458 | 636 | #endif |
|
459 | 637 | ||
460 | static void i830_write_entry(dma_addr_t addr, unsigned int entry, |
638 | static void i830_write_entry(dma_addr_t addr, unsigned int entry, |
Line 509... | Line 687... | ||
509 | if (INTEL_GTT_GEN >= 3) |
687 | if (INTEL_GTT_GEN >= 3) |
510 | writel(0, intel_private.registers+GFX_FLSH_CNTL); |
688 | writel(0, intel_private.registers+GFX_FLSH_CNTL); |
Line 511... | Line 689... | ||
511 | 689 | ||
512 | return true; |
690 | return true; |
- | 691 | } |
|
- | 692 | EXPORT_SYMBOL(intel_enable_gtt); |
|
- | 693 | ||
- | 694 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
|
- | 695 | static int intel_fake_agp_create_gatt_table(struct agp_bridge_data *bridge) |
|
- | 696 | { |
|
- | 697 | agp_bridge->gatt_table_real = NULL; |
|
- | 698 | agp_bridge->gatt_table = NULL; |
|
- | 699 | agp_bridge->gatt_bus_addr = 0; |
|
- | 700 | ||
- | 701 | return 0; |
|
- | 702 | } |
|
- | 703 | ||
- | 704 | static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge) |
|
- | 705 | { |
|
- | 706 | return 0; |
|
- | 707 | } |
|
- | 708 | ||
- | 709 | static int intel_fake_agp_configure(void) |
|
- | 710 | { |
|
- | 711 | if (!intel_enable_gtt()) |
|
- | 712 | return -EIO; |
|
- | 713 | ||
- | 714 | intel_private.clear_fake_agp = true; |
|
- | 715 | agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; |
|
- | 716 | ||
- | 717 | return 0; |
|
- | 718 | } |
|
Line 513... | Line 719... | ||
513 | } |
719 | #endif |
514 | 720 | ||
515 | static bool i830_check_flags(unsigned int flags) |
721 | static bool i830_check_flags(unsigned int flags) |
516 | { |
722 | { |
Line 543... | Line 749... | ||
543 | dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT); |
749 | dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT); |
544 | intel_private.driver->write_entry(addr, j, flags); |
750 | intel_private.driver->write_entry(addr, j, flags); |
545 | j++; |
751 | j++; |
546 | } |
752 | } |
547 | } |
753 | } |
548 | readl(intel_private.gtt+j-1); |
754 | wmb(); |
549 | } |
755 | } |
550 | EXPORT_SYMBOL(intel_gtt_insert_sg_entries); |
756 | EXPORT_SYMBOL(intel_gtt_insert_sg_entries); |
Line 551... | Line 757... | ||
551 | 757 | ||
552 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
758 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
Line 560... | Line 766... | ||
560 | for (i = 0, j = first_entry; i < num_entries; i++, j++) { |
766 | for (i = 0, j = first_entry; i < num_entries; i++, j++) { |
561 | dma_addr_t addr = page_to_phys(pages[i]); |
767 | dma_addr_t addr = page_to_phys(pages[i]); |
562 | intel_private.driver->write_entry(addr, |
768 | intel_private.driver->write_entry(addr, |
563 | j, flags); |
769 | j, flags); |
564 | } |
770 | } |
565 | readl(intel_private.gtt+j-1); |
771 | wmb(); |
566 | } |
772 | } |
Line 567... | Line 773... | ||
567 | 773 | ||
568 | static int intel_fake_agp_insert_entries(struct agp_memory *mem, |
774 | static int intel_fake_agp_insert_entries(struct agp_memory *mem, |
569 | off_t pg_start, int type) |
775 | off_t pg_start, int type) |
Line 623... | Line 829... | ||
623 | 829 | ||
624 | for (i = first_entry; i < (first_entry + num_entries); i++) { |
830 | for (i = first_entry; i < (first_entry + num_entries); i++) { |
625 | intel_private.driver->write_entry(intel_private.scratch_page_dma, |
831 | intel_private.driver->write_entry(intel_private.scratch_page_dma, |
626 | i, 0); |
832 | i, 0); |
627 | } |
833 | } |
628 | readl(intel_private.gtt+i-1); |
834 | wmb(); |
- | 835 | } |
|
- | 836 | EXPORT_SYMBOL(intel_gtt_clear_range); |
|
- | 837 | ||
- | 838 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
|
- | 839 | static int intel_fake_agp_remove_entries(struct agp_memory *mem, |
|
- | 840 | off_t pg_start, int type) |
|
- | 841 | { |
|
- | 842 | if (mem->page_count == 0) |
|
- | 843 | return 0; |
|
- | 844 | ||
- | 845 | intel_gtt_clear_range(pg_start, mem->page_count); |
|
- | 846 | ||
- | 847 | if (intel_private.needs_dmar) { |
|
- | 848 | intel_gtt_unmap_memory(mem->sg_list, mem->num_sg); |
|
- | 849 | mem->sg_list = NULL; |
|
- | 850 | mem->num_sg = 0; |
|
- | 851 | } |
|
- | 852 | ||
- | 853 | return 0; |
|
- | 854 | } |
|
- | 855 | ||
- | 856 | static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count, |
|
- | 857 | int type) |
|
- | 858 | { |
|
- | 859 | struct agp_memory *new; |
|
- | 860 | ||
- | 861 | if (type == AGP_DCACHE_MEMORY && INTEL_GTT_GEN == 1) { |
|
- | 862 | if (pg_count != intel_private.num_dcache_entries) |
|
- | 863 | return NULL; |
|
- | 864 | ||
- | 865 | new = agp_create_memory(1); |
|
- | 866 | if (new == NULL) |
|
- | 867 | return NULL; |
|
- | 868 | ||
- | 869 | new->type = AGP_DCACHE_MEMORY; |
|
- | 870 | new->page_count = pg_count; |
|
- | 871 | new->num_scratch_pages = 0; |
|
- | 872 | agp_free_page_array(new); |
|
- | 873 | return new; |
|
- | 874 | } |
|
- | 875 | if (type == AGP_PHYS_MEMORY) |
|
- | 876 | return alloc_agpphysmem_i8xx(pg_count, type); |
|
- | 877 | /* always return NULL for other allocation types for now */ |
|
- | 878 | return NULL; |
|
- | 879 | } |
|
629 | } |
880 | #endif |
630 | static void intel_i915_setup_chipset_flush(void) |
881 | static void intel_i915_setup_chipset_flush(void) |
631 | { |
882 | { |
632 | int ret; |
883 | int ret; |
Line 767... | Line 1018... | ||
767 | intel_i9xx_setup_flush(); |
1018 | intel_i9xx_setup_flush(); |
Line 768... | Line 1019... | ||
768 | 1019 | ||
769 | return 0; |
1020 | return 0; |
Line -... | Line 1021... | ||
- | 1021 | } |
|
- | 1022 | ||
- | 1023 | #if IS_ENABLED(CONFIG_AGP_INTEL) |
|
- | 1024 | static const struct agp_bridge_driver intel_fake_agp_driver = { |
|
- | 1025 | .owner = THIS_MODULE, |
|
- | 1026 | .size_type = FIXED_APER_SIZE, |
|
- | 1027 | .aperture_sizes = intel_fake_agp_sizes, |
|
- | 1028 | .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), |
|
- | 1029 | .configure = intel_fake_agp_configure, |
|
- | 1030 | .fetch_size = intel_fake_agp_fetch_size, |
|
- | 1031 | .cleanup = intel_gtt_cleanup, |
|
- | 1032 | .agp_enable = intel_fake_agp_enable, |
|
- | 1033 | .cache_flush = global_cache_flush, |
|
- | 1034 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
|
- | 1035 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
|
- | 1036 | .insert_memory = intel_fake_agp_insert_entries, |
|
- | 1037 | .remove_memory = intel_fake_agp_remove_entries, |
|
- | 1038 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
|
- | 1039 | .free_by_type = intel_i810_free_by_type, |
|
- | 1040 | .agp_alloc_page = agp_generic_alloc_page, |
|
- | 1041 | .agp_alloc_pages = agp_generic_alloc_pages, |
|
- | 1042 | .agp_destroy_page = agp_generic_destroy_page, |
|
- | 1043 | .agp_destroy_pages = agp_generic_destroy_pages, |
|
770 | } |
1044 | }; |
771 | 1045 | #endif |
|
772 | static const struct intel_gtt_driver i915_gtt_driver = { |
1046 | static const struct intel_gtt_driver i915_gtt_driver = { |
773 | .gen = 3, |
1047 | .gen = 3, |
774 | .has_pgtbl_enable = 1, |
1048 | .has_pgtbl_enable = 1, |
Line 968... | Line 1242... | ||
968 | 1242 | ||
969 | return 1; |
1243 | return 1; |
970 | } |
1244 | } |
Line 971... | Line 1245... | ||
971 | EXPORT_SYMBOL(intel_gmch_probe); |
1245 | EXPORT_SYMBOL(intel_gmch_probe); |
972 | 1246 | ||
973 | void intel_gtt_get(size_t *gtt_total, size_t *stolen_size, |
1247 | void intel_gtt_get(u64 *gtt_total, size_t *stolen_size, |
974 | phys_addr_t *mappable_base, unsigned long *mappable_end) |
1248 | phys_addr_t *mappable_base, u64 *mappable_end) |
975 | { |
1249 | { |
976 | *gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT; |
1250 | *gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT; |
977 | *stolen_size = intel_private.stolen_size; |
1251 | *stolen_size = intel_private.stolen_size; |
Line 986... | Line 1260... | ||
986 | intel_private.driver->chipset_flush(); |
1260 | intel_private.driver->chipset_flush(); |
987 | } |
1261 | } |
988 | EXPORT_SYMBOL(intel_gtt_chipset_flush); |
1262 | EXPORT_SYMBOL(intel_gtt_chipset_flush); |
Line 989... | Line 1263... | ||
989 | 1263 | ||
990 | 1264 |