Rev 3243 | Rev 4104 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3243 | Rev 3480 | ||
---|---|---|---|
Line 13... | Line 13... | ||
13 | * here. |
13 | * here. |
14 | * |
14 | * |
15 | * /fairy-tale-mode off |
15 | * /fairy-tale-mode off |
16 | */ |
16 | */ |
Line -... | Line 17... | ||
- | 17 | ||
- | 18 | #include |
|
17 | 19 | ||
18 | #include |
20 | #include |
19 | #include |
21 | #include |
20 | #include |
22 | #include |
21 | #include |
23 | #include |
Line 28... | Line 30... | ||
28 | #include |
30 | #include |
29 | #include "agp.h" |
31 | #include "agp.h" |
30 | #include "intel-agp.h" |
32 | #include "intel-agp.h" |
31 | #include |
33 | #include |
Line 32... | Line -... | ||
32 | - | ||
Line 33... | Line 34... | ||
33 | #include |
34 | |
34 | 35 | ||
Line 84... | Line 85... | ||
84 | bool (*check_flags)(unsigned int flags); |
85 | bool (*check_flags)(unsigned int flags); |
85 | void (*chipset_flush)(void); |
86 | void (*chipset_flush)(void); |
86 | }; |
87 | }; |
Line 87... | Line 88... | ||
87 | 88 | ||
88 | static struct _intel_private { |
- | |
89 | struct intel_gtt base; |
89 | static struct _intel_private { |
90 | const struct intel_gtt_driver *driver; |
90 | const struct intel_gtt_driver *driver; |
91 | struct pci_dev *pcidev; /* device one */ |
91 | struct pci_dev *pcidev; /* device one */ |
92 | struct pci_dev *bridge_dev; |
92 | struct pci_dev *bridge_dev; |
93 | u8 __iomem *registers; |
93 | u8 __iomem *registers; |
Line 99... | Line 99... | ||
99 | void __iomem *i9xx_flush_page; |
99 | void __iomem *i9xx_flush_page; |
100 | char *i81x_gtt_table; |
100 | char *i81x_gtt_table; |
101 | struct resource ifp_resource; |
101 | struct resource ifp_resource; |
102 | int resource_valid; |
102 | int resource_valid; |
103 | struct page *scratch_page; |
103 | struct page *scratch_page; |
- | 104 | phys_addr_t scratch_page_dma; |
|
104 | int refcount; |
105 | int refcount; |
- | 106 | /* Whether i915 needs to use the dmar apis or not. */ |
|
- | 107 | unsigned int needs_dmar : 1; |
|
- | 108 | phys_addr_t gma_bus_addr; |
|
- | 109 | /* Size of memory reserved for graphics by the BIOS */ |
|
- | 110 | unsigned int stolen_size; |
|
- | 111 | /* Total number of gtt entries. */ |
|
- | 112 | unsigned int gtt_total_entries; |
|
- | 113 | /* Part of the gtt that is mappable by the cpu, for those chips where |
|
- | 114 | * this is not the full gtt. */ |
|
- | 115 | unsigned int gtt_mappable_entries; |
|
105 | } intel_private; |
116 | } intel_private; |
Line 106... | Line 117... | ||
106 | 117 | ||
107 | #define INTEL_GTT_GEN intel_private.driver->gen |
118 | #define INTEL_GTT_GEN intel_private.driver->gen |
108 | #define IS_G33 intel_private.driver->is_g33 |
119 | #define IS_G33 intel_private.driver->is_g33 |
Line 116... | Line 127... | ||
116 | dma_addr_t dma_addr; |
127 | dma_addr_t dma_addr; |
Line 117... | Line 128... | ||
117 | 128 | ||
118 | page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); |
129 | page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); |
119 | if (page == NULL) |
130 | if (page == NULL) |
120 | return -ENOMEM; |
131 | return -ENOMEM; |
Line 121... | Line 132... | ||
121 | intel_private.base.scratch_page_dma = page_to_phys(page); |
132 | intel_private.scratch_page_dma = page_to_phys(page); |
Line 122... | Line 133... | ||
122 | 133 | ||
123 | intel_private.scratch_page = page; |
134 | intel_private.scratch_page = page; |
Line 298... | Line 309... | ||
298 | return i965_gtt_total_entries(); |
309 | return i965_gtt_total_entries(); |
299 | else { |
310 | else { |
300 | /* On previous hardware, the GTT size was just what was |
311 | /* On previous hardware, the GTT size was just what was |
301 | * required to map the aperture. |
312 | * required to map the aperture. |
302 | */ |
313 | */ |
303 | return intel_private.base.gtt_mappable_entries; |
314 | return intel_private.gtt_mappable_entries; |
304 | } |
315 | } |
305 | } |
316 | } |
Line 306... | Line 317... | ||
306 | 317 | ||
307 | static unsigned int intel_gtt_mappable_entries(void) |
318 | static unsigned int intel_gtt_mappable_entries(void) |
Line 360... | Line 371... | ||
360 | 371 | ||
361 | ret = intel_private.driver->setup(); |
372 | ret = intel_private.driver->setup(); |
362 | if (ret != 0) |
373 | if (ret != 0) |
Line 363... | Line 374... | ||
363 | return ret; |
374 | return ret; |
364 | 375 | ||
Line 365... | Line 376... | ||
365 | intel_private.base.gtt_mappable_entries = intel_gtt_mappable_entries(); |
376 | intel_private.gtt_mappable_entries = intel_gtt_mappable_entries(); |
366 | intel_private.base.gtt_total_entries = intel_gtt_total_entries(); |
377 | intel_private.gtt_total_entries = intel_gtt_total_entries(); |
367 | 378 | ||
368 | /* save the PGETBL reg for resume */ |
379 | /* save the PGETBL reg for resume */ |
Line 373... | Line 384... | ||
373 | if (HAS_PGTBL_EN) |
384 | if (HAS_PGTBL_EN) |
374 | intel_private.PGETBL_save |= I810_PGETBL_ENABLED; |
385 | intel_private.PGETBL_save |= I810_PGETBL_ENABLED; |
Line 375... | Line 386... | ||
375 | 386 | ||
376 | dev_info(&intel_private.bridge_dev->dev, |
387 | dev_info(&intel_private.bridge_dev->dev, |
377 | "detected gtt size: %dK total, %dK mappable\n", |
388 | "detected gtt size: %dK total, %dK mappable\n", |
378 | intel_private.base.gtt_total_entries * 4, |
389 | intel_private.gtt_total_entries * 4, |
Line 379... | Line 390... | ||
379 | intel_private.base.gtt_mappable_entries * 4); |
390 | intel_private.gtt_mappable_entries * 4); |
Line 380... | Line 391... | ||
380 | 391 | ||
381 | gtt_map_size = intel_private.base.gtt_total_entries * 4; |
392 | gtt_map_size = intel_private.gtt_total_entries * 4; |
382 | 393 | ||
383 | intel_private.gtt = NULL; |
394 | intel_private.gtt = NULL; |
384 | if (intel_private.gtt == NULL) |
395 | if (intel_private.gtt == NULL) |
385 | intel_private.gtt = ioremap(intel_private.gtt_bus_addr, |
396 | intel_private.gtt = ioremap(intel_private.gtt_bus_addr, |
386 | gtt_map_size); |
397 | gtt_map_size); |
387 | if (intel_private.gtt == NULL) { |
398 | if (intel_private.gtt == NULL) { |
388 | intel_private.driver->cleanup(); |
399 | intel_private.driver->cleanup(); |
389 | iounmap(intel_private.registers); |
- | |
Line 390... | Line 400... | ||
390 | return -ENOMEM; |
400 | iounmap(intel_private.registers); |
Line 391... | Line 401... | ||
391 | } |
401 | return -ENOMEM; |
Line 392... | Line 402... | ||
392 | intel_private.base.gtt = intel_private.gtt; |
402 | } |
Line 393... | Line 403... | ||
393 | 403 | ||
394 | asm volatile("wbinvd"); |
404 | asm volatile("wbinvd"); |
395 | 405 | ||
396 | intel_private.base.stolen_size = intel_gtt_stolen_size(); |
406 | intel_private.stolen_size = intel_gtt_stolen_size(); |
Line 408... | Line 418... | ||
408 | &gma_addr); |
418 | &gma_addr); |
409 | else |
419 | else |
410 | pci_read_config_dword(intel_private.pcidev, I915_GMADDR, |
420 | pci_read_config_dword(intel_private.pcidev, I915_GMADDR, |
411 | &gma_addr); |
421 | &gma_addr); |
Line 412... | Line 422... | ||
412 | 422 | ||
- | 423 | intel_private.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); |
|
Line 413... | Line 424... | ||
413 | intel_private.base.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); |
424 | |
414 | 425 | ||
Line 415... | Line 426... | ||
415 | return 0; |
426 | return 0; |
Line 526... | Line 537... | ||
526 | void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) |
537 | void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) |
527 | { |
538 | { |
528 | unsigned int i; |
539 | unsigned int i; |
Line 529... | Line 540... | ||
529 | 540 | ||
530 | for (i = first_entry; i < (first_entry + num_entries); i++) { |
541 | for (i = first_entry; i < (first_entry + num_entries); i++) { |
531 | intel_private.driver->write_entry(intel_private.base.scratch_page_dma, |
542 | intel_private.driver->write_entry(intel_private.scratch_page_dma, |
532 | i, 0); |
543 | i, 0); |
533 | } |
544 | } |
534 | readl(intel_private.gtt+i-1); |
545 | readl(intel_private.gtt+i-1); |
Line 592... | Line 603... | ||
592 | /* Shift high bits down */ |
603 | /* Shift high bits down */ |
593 | addr |= (addr >> 28) & 0xf0; |
604 | addr |= (addr >> 28) & 0xf0; |
594 | writel(addr | pte_flags, intel_private.gtt + entry); |
605 | writel(addr | pte_flags, intel_private.gtt + entry); |
595 | } |
606 | } |
Line 596... | Line -... | ||
596 | - | ||
597 | /* Certain Gen5 chipsets require require idling the GPU before |
- | |
598 | * unmapping anything from the GTT when VT-d is enabled. |
- | |
599 | */ |
- | |
600 | static inline int needs_idle_maps(void) |
- | |
601 | { |
- | |
602 | #ifdef CONFIG_INTEL_IOMMU |
- | |
603 | const unsigned short gpu_devid = intel_private.pcidev->device; |
- | |
604 | - | ||
605 | /* Query intel_iommu to see if we need the workaround. Presumably that |
- | |
606 | * was loaded first. |
- | |
607 | */ |
- | |
608 | if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || |
- | |
609 | gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && |
- | |
610 | intel_iommu_gfx_mapped) |
- | |
611 | return 1; |
- | |
612 | #endif |
- | |
613 | return 0; |
- | |
614 | } |
- | |
615 | 607 | ||
616 | static int i9xx_setup(void) |
608 | static int i9xx_setup(void) |
617 | { |
609 | { |
618 | u32 reg_addr, gtt_addr; |
610 | u32 reg_addr, gtt_addr; |
Line 638... | Line 630... | ||
638 | default: |
630 | default: |
639 | intel_private.gtt_bus_addr = reg_addr + KB(512); |
631 | intel_private.gtt_bus_addr = reg_addr + KB(512); |
640 | break; |
632 | break; |
641 | } |
633 | } |
Line 642... | Line -... | ||
642 | - | ||
643 | if (needs_idle_maps()) |
- | |
644 | intel_private.base.do_idle_maps = 1; |
- | |
645 | 634 | ||
Line 646... | Line 635... | ||
646 | intel_i9xx_setup_flush(); |
635 | intel_i9xx_setup_flush(); |
647 | 636 | ||
Line 792... | Line 781... | ||
792 | 781 | ||
793 | int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, |
782 | int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, |
794 | struct agp_bridge_data *bridge) |
783 | struct agp_bridge_data *bridge) |
795 | { |
784 | { |
- | 785 | int i, mask; |
|
- | 786 | ||
- | 787 | /* |
|
- | 788 | * Can be called from the fake agp driver but also directly from |
|
- | 789 | * drm/i915.ko. Hence we need to check whether everything is set up |
|
- | 790 | * already. |
|
796 | int i, mask; |
791 | */ |
- | 792 | if (intel_private.driver) { |
|
- | 793 | intel_private.refcount++; |
|
- | 794 | return 1; |
|
- | 795 | } |
|
Line 797... | Line 796... | ||
797 | intel_private.driver = NULL; |
796 | |
798 | 797 | ||
799 | for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { |
798 | for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { |
800 | if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { |
799 | if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { |
Line 805... | Line 804... | ||
805 | } |
804 | } |
Line 806... | Line 805... | ||
806 | 805 | ||
807 | if (!intel_private.driver) |
806 | if (!intel_private.driver) |
Line -... | Line 807... | ||
- | 807 | return 0; |
|
- | 808 | ||
808 | return 0; |
809 | intel_private.refcount++; |
809 | 810 | ||
810 | if (bridge) { |
811 | if (bridge) { |
811 | bridge->dev_private_data = &intel_private; |
812 | bridge->dev_private_data = &intel_private; |
Line 832... | Line 833... | ||
832 | 833 | ||
833 | return 1; |
834 | return 1; |
834 | } |
835 | } |
Line 835... | Line 836... | ||
835 | EXPORT_SYMBOL(intel_gmch_probe); |
836 | EXPORT_SYMBOL(intel_gmch_probe); |
- | 837 | ||
836 | 838 | void intel_gtt_get(size_t *gtt_total, size_t *stolen_size, |
|
- | 839 | phys_addr_t *mappable_base, unsigned long *mappable_end) |
|
837 | struct intel_gtt *intel_gtt_get(void) |
840 | { |
- | 841 | *gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT; |
|
- | 842 | *stolen_size = intel_private.stolen_size; |
|
838 | { |
843 | *mappable_base = intel_private.gma_bus_addr; |
839 | return &intel_private.base; |
844 | *mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT; |
Line 840... | Line 845... | ||
840 | } |
845 | } |
841 | EXPORT_SYMBOL(intel_gtt_get); |
846 | EXPORT_SYMBOL(intel_gtt_get); |