diff options
Diffstat (limited to 'drivers/char/agp/intel-agp.c')
-rw-r--r-- | drivers/char/agp/intel-agp.c | 138 |
1 files changed, 117 insertions, 21 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 45a22f9bfec2..a3e10dc7cc25 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -8,8 +8,12 @@ | |||
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/pagemap.h> | 9 | #include <linux/pagemap.h> |
10 | #include <linux/agp_backend.h> | 10 | #include <linux/agp_backend.h> |
11 | #include <asm/smp.h> | ||
11 | #include "agp.h" | 12 | #include "agp.h" |
12 | 13 | ||
14 | int intel_agp_enabled; | ||
15 | EXPORT_SYMBOL(intel_agp_enabled); | ||
16 | |||
13 | /* | 17 | /* |
14 | * If we have Intel graphics, we're not going to have anything other than | 18 | * If we have Intel graphics, we're not going to have anything other than |
15 | * an Intel IOMMU. So make the correct use of the PCI DMA API contingent | 19 | * an Intel IOMMU. So make the correct use of the PCI DMA API contingent |
@@ -64,6 +68,10 @@ | |||
64 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 | 68 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 |
65 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a | 69 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a |
66 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046 | 70 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046 |
71 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB 0x0100 | ||
72 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102 | ||
73 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 | ||
74 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106 | ||
67 | 75 | ||
68 | /* cover 915 and 945 variants */ | 76 | /* cover 915 and 945 variants */ |
69 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | 77 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ |
@@ -98,7 +106,9 @@ | |||
98 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \ | 106 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \ |
99 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \ | 107 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \ |
100 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ | 108 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ |
101 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB) | 109 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ |
110 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ | ||
111 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) | ||
102 | 112 | ||
103 | extern int agp_memory_reserved; | 113 | extern int agp_memory_reserved; |
104 | 114 | ||
@@ -147,6 +157,25 @@ extern int agp_memory_reserved; | |||
147 | #define INTEL_I7505_AGPCTRL 0x70 | 157 | #define INTEL_I7505_AGPCTRL 0x70 |
148 | #define INTEL_I7505_MCHCFG 0x50 | 158 | #define INTEL_I7505_MCHCFG 0x50 |
149 | 159 | ||
160 | #define SNB_GMCH_CTRL 0x50 | ||
161 | #define SNB_GMCH_GMS_STOLEN_MASK 0xF8 | ||
162 | #define SNB_GMCH_GMS_STOLEN_32M (1 << 3) | ||
163 | #define SNB_GMCH_GMS_STOLEN_64M (2 << 3) | ||
164 | #define SNB_GMCH_GMS_STOLEN_96M (3 << 3) | ||
165 | #define SNB_GMCH_GMS_STOLEN_128M (4 << 3) | ||
166 | #define SNB_GMCH_GMS_STOLEN_160M (5 << 3) | ||
167 | #define SNB_GMCH_GMS_STOLEN_192M (6 << 3) | ||
168 | #define SNB_GMCH_GMS_STOLEN_224M (7 << 3) | ||
169 | #define SNB_GMCH_GMS_STOLEN_256M (8 << 3) | ||
170 | #define SNB_GMCH_GMS_STOLEN_288M (9 << 3) | ||
171 | #define SNB_GMCH_GMS_STOLEN_320M (0xa << 3) | ||
172 | #define SNB_GMCH_GMS_STOLEN_352M (0xb << 3) | ||
173 | #define SNB_GMCH_GMS_STOLEN_384M (0xc << 3) | ||
174 | #define SNB_GMCH_GMS_STOLEN_416M (0xd << 3) | ||
175 | #define SNB_GMCH_GMS_STOLEN_448M (0xe << 3) | ||
176 | #define SNB_GMCH_GMS_STOLEN_480M (0xf << 3) | ||
177 | #define SNB_GMCH_GMS_STOLEN_512M (0x10 << 3) | ||
178 | |||
150 | static const struct aper_size_info_fixed intel_i810_sizes[] = | 179 | static const struct aper_size_info_fixed intel_i810_sizes[] = |
151 | { | 180 | { |
152 | {64, 16384, 4}, | 181 | {64, 16384, 4}, |
@@ -293,6 +322,13 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem, | |||
293 | off_t pg_start, int mask_type) | 322 | off_t pg_start, int mask_type) |
294 | { | 323 | { |
295 | int i, j; | 324 | int i, j; |
325 | u32 cache_bits = 0; | ||
326 | |||
327 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || | ||
328 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) | ||
329 | { | ||
330 | cache_bits = I830_PTE_SYSTEM_CACHED; | ||
331 | } | ||
296 | 332 | ||
297 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 333 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
298 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 334 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
@@ -613,7 +649,7 @@ static struct aper_size_info_fixed intel_i830_sizes[] = | |||
613 | static void intel_i830_init_gtt_entries(void) | 649 | static void intel_i830_init_gtt_entries(void) |
614 | { | 650 | { |
615 | u16 gmch_ctrl; | 651 | u16 gmch_ctrl; |
616 | int gtt_entries; | 652 | int gtt_entries = 0; |
617 | u8 rdct; | 653 | u8 rdct; |
618 | int local = 0; | 654 | int local = 0; |
619 | static const int ddt[4] = { 0, 16, 32, 64 }; | 655 | static const int ddt[4] = { 0, 16, 32, 64 }; |
@@ -705,6 +741,63 @@ static void intel_i830_init_gtt_entries(void) | |||
705 | gtt_entries = 0; | 741 | gtt_entries = 0; |
706 | break; | 742 | break; |
707 | } | 743 | } |
744 | } else if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || | ||
745 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) { | ||
746 | /* | ||
747 | * SandyBridge has new memory control reg at 0x50.w | ||
748 | */ | ||
749 | u16 snb_gmch_ctl; | ||
750 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | ||
751 | switch (snb_gmch_ctl & SNB_GMCH_GMS_STOLEN_MASK) { | ||
752 | case SNB_GMCH_GMS_STOLEN_32M: | ||
753 | gtt_entries = MB(32) - KB(size); | ||
754 | break; | ||
755 | case SNB_GMCH_GMS_STOLEN_64M: | ||
756 | gtt_entries = MB(64) - KB(size); | ||
757 | break; | ||
758 | case SNB_GMCH_GMS_STOLEN_96M: | ||
759 | gtt_entries = MB(96) - KB(size); | ||
760 | break; | ||
761 | case SNB_GMCH_GMS_STOLEN_128M: | ||
762 | gtt_entries = MB(128) - KB(size); | ||
763 | break; | ||
764 | case SNB_GMCH_GMS_STOLEN_160M: | ||
765 | gtt_entries = MB(160) - KB(size); | ||
766 | break; | ||
767 | case SNB_GMCH_GMS_STOLEN_192M: | ||
768 | gtt_entries = MB(192) - KB(size); | ||
769 | break; | ||
770 | case SNB_GMCH_GMS_STOLEN_224M: | ||
771 | gtt_entries = MB(224) - KB(size); | ||
772 | break; | ||
773 | case SNB_GMCH_GMS_STOLEN_256M: | ||
774 | gtt_entries = MB(256) - KB(size); | ||
775 | break; | ||
776 | case SNB_GMCH_GMS_STOLEN_288M: | ||
777 | gtt_entries = MB(288) - KB(size); | ||
778 | break; | ||
779 | case SNB_GMCH_GMS_STOLEN_320M: | ||
780 | gtt_entries = MB(320) - KB(size); | ||
781 | break; | ||
782 | case SNB_GMCH_GMS_STOLEN_352M: | ||
783 | gtt_entries = MB(352) - KB(size); | ||
784 | break; | ||
785 | case SNB_GMCH_GMS_STOLEN_384M: | ||
786 | gtt_entries = MB(384) - KB(size); | ||
787 | break; | ||
788 | case SNB_GMCH_GMS_STOLEN_416M: | ||
789 | gtt_entries = MB(416) - KB(size); | ||
790 | break; | ||
791 | case SNB_GMCH_GMS_STOLEN_448M: | ||
792 | gtt_entries = MB(448) - KB(size); | ||
793 | break; | ||
794 | case SNB_GMCH_GMS_STOLEN_480M: | ||
795 | gtt_entries = MB(480) - KB(size); | ||
796 | break; | ||
797 | case SNB_GMCH_GMS_STOLEN_512M: | ||
798 | gtt_entries = MB(512) - KB(size); | ||
799 | break; | ||
800 | } | ||
708 | } else { | 801 | } else { |
709 | switch (gmch_ctrl & I855_GMCH_GMS_MASK) { | 802 | switch (gmch_ctrl & I855_GMCH_GMS_MASK) { |
710 | case I855_GMCH_GMS_STOLEN_1M: | 803 | case I855_GMCH_GMS_STOLEN_1M: |
@@ -815,12 +908,6 @@ static void intel_i830_setup_flush(void) | |||
815 | intel_i830_fini_flush(); | 908 | intel_i830_fini_flush(); |
816 | } | 909 | } |
817 | 910 | ||
818 | static void | ||
819 | do_wbinvd(void *null) | ||
820 | { | ||
821 | wbinvd(); | ||
822 | } | ||
823 | |||
824 | /* The chipset_flush interface needs to get data that has already been | 911 | /* The chipset_flush interface needs to get data that has already been |
825 | * flushed out of the CPU all the way out to main memory, because the GPU | 912 | * flushed out of the CPU all the way out to main memory, because the GPU |
826 | * doesn't snoop those buffers. | 913 | * doesn't snoop those buffers. |
@@ -837,12 +924,10 @@ static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) | |||
837 | 924 | ||
838 | memset(pg, 0, 1024); | 925 | memset(pg, 0, 1024); |
839 | 926 | ||
840 | if (cpu_has_clflush) { | 927 | if (cpu_has_clflush) |
841 | clflush_cache_range(pg, 1024); | 928 | clflush_cache_range(pg, 1024); |
842 | } else { | 929 | else if (wbinvd_on_all_cpus() != 0) |
843 | if (on_each_cpu(do_wbinvd, NULL, 1) != 0) | 930 | printk(KERN_ERR "Timed out waiting for cache flush.\n"); |
844 | printk(KERN_ERR "Timed out waiting for cache flush.\n"); | ||
845 | } | ||
846 | } | 931 | } |
847 | 932 | ||
848 | /* The intel i830 automatically initializes the agp aperture during POST. | 933 | /* The intel i830 automatically initializes the agp aperture during POST. |
@@ -1364,6 +1449,8 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | |||
1364 | case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB: | 1449 | case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB: |
1365 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB: | 1450 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB: |
1366 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB: | 1451 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB: |
1452 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: | ||
1453 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: | ||
1367 | *gtt_offset = *gtt_size = MB(2); | 1454 | *gtt_offset = *gtt_size = MB(2); |
1368 | break; | 1455 | break; |
1369 | default: | 1456 | default: |
@@ -2345,9 +2432,9 @@ static const struct intel_driver_description { | |||
2345 | NULL, &intel_g33_driver }, | 2432 | NULL, &intel_g33_driver }, |
2346 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", | 2433 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", |
2347 | NULL, &intel_g33_driver }, | 2434 | NULL, &intel_g33_driver }, |
2348 | { PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "Pineview", | 2435 | { PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "GMA3150", |
2349 | NULL, &intel_g33_driver }, | 2436 | NULL, &intel_g33_driver }, |
2350 | { PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "Pineview", | 2437 | { PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "GMA3150", |
2351 | NULL, &intel_g33_driver }, | 2438 | NULL, &intel_g33_driver }, |
2352 | { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, | 2439 | { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, |
2353 | "GM45", NULL, &intel_i965_driver }, | 2440 | "GM45", NULL, &intel_i965_driver }, |
@@ -2362,13 +2449,17 @@ static const struct intel_driver_description { | |||
2362 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, | 2449 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, |
2363 | "G41", NULL, &intel_i965_driver }, | 2450 | "G41", NULL, &intel_i965_driver }, |
2364 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0, | 2451 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0, |
2365 | "Ironlake/D", NULL, &intel_i965_driver }, | 2452 | "HD Graphics", NULL, &intel_i965_driver }, |
2366 | { PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, | 2453 | { PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, |
2367 | "Ironlake/M", NULL, &intel_i965_driver }, | 2454 | "HD Graphics", NULL, &intel_i965_driver }, |
2368 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, | 2455 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, |
2369 | "Ironlake/MA", NULL, &intel_i965_driver }, | 2456 | "HD Graphics", NULL, &intel_i965_driver }, |
2370 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, | 2457 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, |
2371 | "Ironlake/MC2", NULL, &intel_i965_driver }, | 2458 | "HD Graphics", NULL, &intel_i965_driver }, |
2459 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG, 0, | ||
2460 | "Sandybridge", NULL, &intel_i965_driver }, | ||
2461 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG, 0, | ||
2462 | "Sandybridge", NULL, &intel_i965_driver }, | ||
2372 | { 0, 0, 0, NULL, NULL, NULL } | 2463 | { 0, 0, 0, NULL, NULL, NULL } |
2373 | }; | 2464 | }; |
2374 | 2465 | ||
@@ -2378,7 +2469,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2378 | struct agp_bridge_data *bridge; | 2469 | struct agp_bridge_data *bridge; |
2379 | u8 cap_ptr = 0; | 2470 | u8 cap_ptr = 0; |
2380 | struct resource *r; | 2471 | struct resource *r; |
2381 | int i; | 2472 | int i, err; |
2382 | 2473 | ||
2383 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); | 2474 | cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); |
2384 | 2475 | ||
@@ -2470,7 +2561,10 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2470 | } | 2561 | } |
2471 | 2562 | ||
2472 | pci_set_drvdata(pdev, bridge); | 2563 | pci_set_drvdata(pdev, bridge); |
2473 | return agp_add_bridge(bridge); | 2564 | err = agp_add_bridge(bridge); |
2565 | if (!err) | ||
2566 | intel_agp_enabled = 1; | ||
2567 | return err; | ||
2474 | } | 2568 | } |
2475 | 2569 | ||
2476 | static void __devexit agp_intel_remove(struct pci_dev *pdev) | 2570 | static void __devexit agp_intel_remove(struct pci_dev *pdev) |
@@ -2575,6 +2669,8 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2575 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), | 2669 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), |
2576 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), | 2670 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), |
2577 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), | 2671 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), |
2672 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), | ||
2673 | ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), | ||
2578 | { } | 2674 | { } |
2579 | }; | 2675 | }; |
2580 | 2676 | ||