diff options
Diffstat (limited to 'drivers/char/agp/intel-agp.c')
-rw-r--r-- | drivers/char/agp/intel-agp.c | 305 |
1 files changed, 242 insertions, 63 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 189efb6ef970..eeea50a1d22a 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -14,8 +14,8 @@ | |||
14 | #define PCI_DEVICE_ID_INTEL_E7221_IG 0x258a | 14 | #define PCI_DEVICE_ID_INTEL_E7221_IG 0x258a |
15 | #define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970 | 15 | #define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970 |
16 | #define PCI_DEVICE_ID_INTEL_82946GZ_IG 0x2972 | 16 | #define PCI_DEVICE_ID_INTEL_82946GZ_IG 0x2972 |
17 | #define PCI_DEVICE_ID_INTEL_82965G_1_HB 0x2980 | 17 | #define PCI_DEVICE_ID_INTEL_82G35_HB 0x2980 |
18 | #define PCI_DEVICE_ID_INTEL_82965G_1_IG 0x2982 | 18 | #define PCI_DEVICE_ID_INTEL_82G35_IG 0x2982 |
19 | #define PCI_DEVICE_ID_INTEL_82965Q_HB 0x2990 | 19 | #define PCI_DEVICE_ID_INTEL_82965Q_HB 0x2990 |
20 | #define PCI_DEVICE_ID_INTEL_82965Q_IG 0x2992 | 20 | #define PCI_DEVICE_ID_INTEL_82965Q_IG 0x2992 |
21 | #define PCI_DEVICE_ID_INTEL_82965G_HB 0x29A0 | 21 | #define PCI_DEVICE_ID_INTEL_82965G_HB 0x29A0 |
@@ -32,13 +32,24 @@ | |||
32 | #define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2 | 32 | #define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2 |
33 | #define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0 | 33 | #define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0 |
34 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 | 34 | #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 |
35 | #define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40 | ||
36 | #define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42 | ||
37 | |||
38 | /* cover 915 and 945 variants */ | ||
39 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | ||
40 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || \ | ||
41 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || \ | ||
42 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || \ | ||
43 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || \ | ||
44 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB) | ||
35 | 45 | ||
36 | #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ | 46 | #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ |
37 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ | 47 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82G35_HB || \ |
38 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ | 48 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ |
39 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ | 49 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ |
40 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ | 50 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ |
41 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) | 51 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \ |
52 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB) | ||
42 | 53 | ||
43 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ | 54 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ |
44 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ | 55 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ |
@@ -71,9 +82,11 @@ extern int agp_memory_reserved; | |||
71 | #define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) | 82 | #define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) |
72 | #define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) | 83 | #define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) |
73 | #define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) | 84 | #define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) |
85 | #define I915_IFPADDR 0x60 | ||
74 | 86 | ||
75 | /* Intel 965G registers */ | 87 | /* Intel 965G registers */ |
76 | #define I965_MSAC 0x62 | 88 | #define I965_MSAC 0x62 |
89 | #define I965_IFPADDR 0x70 | ||
77 | 90 | ||
78 | /* Intel 7505 registers */ | 91 | /* Intel 7505 registers */ |
79 | #define INTEL_I7505_APSIZE 0x74 | 92 | #define INTEL_I7505_APSIZE 0x74 |
@@ -115,6 +128,13 @@ static struct _intel_private { | |||
115 | * popup and for the GTT. | 128 | * popup and for the GTT. |
116 | */ | 129 | */ |
117 | int gtt_entries; /* i830+ */ | 130 | int gtt_entries; /* i830+ */ |
131 | union { | ||
132 | void __iomem *i9xx_flush_page; | ||
133 | void *i8xx_flush_page; | ||
134 | }; | ||
135 | struct page *i8xx_page; | ||
136 | struct resource ifp_resource; | ||
137 | int resource_valid; | ||
118 | } intel_private; | 138 | } intel_private; |
119 | 139 | ||
120 | static int intel_i810_fetch_size(void) | 140 | static int intel_i810_fetch_size(void) |
@@ -204,7 +224,7 @@ static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode) | |||
204 | /* Exists to support ARGB cursors */ | 224 | /* Exists to support ARGB cursors */ |
205 | static void *i8xx_alloc_pages(void) | 225 | static void *i8xx_alloc_pages(void) |
206 | { | 226 | { |
207 | struct page * page; | 227 | struct page *page; |
208 | 228 | ||
209 | page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2); | 229 | page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2); |
210 | if (page == NULL) | 230 | if (page == NULL) |
@@ -433,7 +453,7 @@ static void intel_i830_init_gtt_entries(void) | |||
433 | static const int ddt[4] = { 0, 16, 32, 64 }; | 453 | static const int ddt[4] = { 0, 16, 32, 64 }; |
434 | int size; /* reserved space (in kb) at the top of stolen memory */ | 454 | int size; /* reserved space (in kb) at the top of stolen memory */ |
435 | 455 | ||
436 | pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); | 456 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); |
437 | 457 | ||
438 | if (IS_I965) { | 458 | if (IS_I965) { |
439 | u32 pgetbl_ctl; | 459 | u32 pgetbl_ctl; |
@@ -453,6 +473,15 @@ static void intel_i830_init_gtt_entries(void) | |||
453 | case I965_PGETBL_SIZE_512KB: | 473 | case I965_PGETBL_SIZE_512KB: |
454 | size = 512; | 474 | size = 512; |
455 | break; | 475 | break; |
476 | case I965_PGETBL_SIZE_1MB: | ||
477 | size = 1024; | ||
478 | break; | ||
479 | case I965_PGETBL_SIZE_2MB: | ||
480 | size = 2048; | ||
481 | break; | ||
482 | case I965_PGETBL_SIZE_1_5MB: | ||
483 | size = 1024 + 512; | ||
484 | break; | ||
456 | default: | 485 | default: |
457 | printk(KERN_INFO PFX "Unknown page table size, " | 486 | printk(KERN_INFO PFX "Unknown page table size, " |
458 | "assuming 512KB\n"); | 487 | "assuming 512KB\n"); |
@@ -523,26 +552,14 @@ static void intel_i830_init_gtt_entries(void) | |||
523 | break; | 552 | break; |
524 | case I915_GMCH_GMS_STOLEN_48M: | 553 | case I915_GMCH_GMS_STOLEN_48M: |
525 | /* Check it's really I915G */ | 554 | /* Check it's really I915G */ |
526 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || | 555 | if (IS_I915 || IS_I965 || IS_G33) |
527 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || | ||
528 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || | ||
529 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || | ||
530 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || | ||
531 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || | ||
532 | IS_I965 || IS_G33) | ||
533 | gtt_entries = MB(48) - KB(size); | 556 | gtt_entries = MB(48) - KB(size); |
534 | else | 557 | else |
535 | gtt_entries = 0; | 558 | gtt_entries = 0; |
536 | break; | 559 | break; |
537 | case I915_GMCH_GMS_STOLEN_64M: | 560 | case I915_GMCH_GMS_STOLEN_64M: |
538 | /* Check it's really I915G */ | 561 | /* Check it's really I915G */ |
539 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || | 562 | if (IS_I915 || IS_I965 || IS_G33) |
540 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || | ||
541 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || | ||
542 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || | ||
543 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || | ||
544 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || | ||
545 | IS_I965 || IS_G33) | ||
546 | gtt_entries = MB(64) - KB(size); | 563 | gtt_entries = MB(64) - KB(size); |
547 | else | 564 | else |
548 | gtt_entries = 0; | 565 | gtt_entries = 0; |
@@ -575,6 +592,45 @@ static void intel_i830_init_gtt_entries(void) | |||
575 | intel_private.gtt_entries = gtt_entries; | 592 | intel_private.gtt_entries = gtt_entries; |
576 | } | 593 | } |
577 | 594 | ||
595 | static void intel_i830_fini_flush(void) | ||
596 | { | ||
597 | kunmap(intel_private.i8xx_page); | ||
598 | intel_private.i8xx_flush_page = NULL; | ||
599 | unmap_page_from_agp(intel_private.i8xx_page); | ||
600 | |||
601 | __free_page(intel_private.i8xx_page); | ||
602 | intel_private.i8xx_page = NULL; | ||
603 | } | ||
604 | |||
605 | static void intel_i830_setup_flush(void) | ||
606 | { | ||
607 | /* return if we've already set the flush mechanism up */ | ||
608 | if (intel_private.i8xx_page) | ||
609 | return; | ||
610 | |||
611 | intel_private.i8xx_page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32); | ||
612 | if (!intel_private.i8xx_page) | ||
613 | return; | ||
614 | |||
615 | /* make page uncached */ | ||
616 | map_page_into_agp(intel_private.i8xx_page); | ||
617 | |||
618 | intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page); | ||
619 | if (!intel_private.i8xx_flush_page) | ||
620 | intel_i830_fini_flush(); | ||
621 | } | ||
622 | |||
623 | static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) | ||
624 | { | ||
625 | unsigned int *pg = intel_private.i8xx_flush_page; | ||
626 | int i; | ||
627 | |||
628 | for (i = 0; i < 256; i += 2) | ||
629 | *(pg + i) = i; | ||
630 | |||
631 | wmb(); | ||
632 | } | ||
633 | |||
578 | /* The intel i830 automatically initializes the agp aperture during POST. | 634 | /* The intel i830 automatically initializes the agp aperture during POST. |
579 | * Use the memory already set aside for in the GTT. | 635 | * Use the memory already set aside for in the GTT. |
580 | */ | 636 | */ |
@@ -590,10 +646,10 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge) | |||
590 | num_entries = size->num_entries; | 646 | num_entries = size->num_entries; |
591 | agp_bridge->gatt_table_real = NULL; | 647 | agp_bridge->gatt_table_real = NULL; |
592 | 648 | ||
593 | pci_read_config_dword(intel_private.pcidev,I810_MMADDR,&temp); | 649 | pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp); |
594 | temp &= 0xfff80000; | 650 | temp &= 0xfff80000; |
595 | 651 | ||
596 | intel_private.registers = ioremap(temp,128 * 4096); | 652 | intel_private.registers = ioremap(temp, 128 * 4096); |
597 | if (!intel_private.registers) | 653 | if (!intel_private.registers) |
598 | return -ENOMEM; | 654 | return -ENOMEM; |
599 | 655 | ||
@@ -633,7 +689,7 @@ static int intel_i830_fetch_size(void) | |||
633 | return values[0].size; | 689 | return values[0].size; |
634 | } | 690 | } |
635 | 691 | ||
636 | pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); | 692 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); |
637 | 693 | ||
638 | if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { | 694 | if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { |
639 | agp_bridge->previous_size = agp_bridge->current_size = (void *) values; | 695 | agp_bridge->previous_size = agp_bridge->current_size = (void *) values; |
@@ -657,12 +713,12 @@ static int intel_i830_configure(void) | |||
657 | 713 | ||
658 | current_size = A_SIZE_FIX(agp_bridge->current_size); | 714 | current_size = A_SIZE_FIX(agp_bridge->current_size); |
659 | 715 | ||
660 | pci_read_config_dword(intel_private.pcidev,I810_GMADDR,&temp); | 716 | pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp); |
661 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | 717 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); |
662 | 718 | ||
663 | pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); | 719 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); |
664 | gmch_ctrl |= I830_GMCH_ENABLED; | 720 | gmch_ctrl |= I830_GMCH_ENABLED; |
665 | pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); | 721 | pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl); |
666 | 722 | ||
667 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); | 723 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); |
668 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | 724 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ |
@@ -675,6 +731,8 @@ static int intel_i830_configure(void) | |||
675 | } | 731 | } |
676 | 732 | ||
677 | global_cache_flush(); | 733 | global_cache_flush(); |
734 | |||
735 | intel_i830_setup_flush(); | ||
678 | return 0; | 736 | return 0; |
679 | } | 737 | } |
680 | 738 | ||
@@ -683,9 +741,10 @@ static void intel_i830_cleanup(void) | |||
683 | iounmap(intel_private.registers); | 741 | iounmap(intel_private.registers); |
684 | } | 742 | } |
685 | 743 | ||
686 | static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int type) | 744 | static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, |
745 | int type) | ||
687 | { | 746 | { |
688 | int i,j,num_entries; | 747 | int i, j, num_entries; |
689 | void *temp; | 748 | void *temp; |
690 | int ret = -EINVAL; | 749 | int ret = -EINVAL; |
691 | int mask_type; | 750 | int mask_type; |
@@ -697,10 +756,10 @@ static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start, int | |||
697 | num_entries = A_SIZE_FIX(temp)->num_entries; | 756 | num_entries = A_SIZE_FIX(temp)->num_entries; |
698 | 757 | ||
699 | if (pg_start < intel_private.gtt_entries) { | 758 | if (pg_start < intel_private.gtt_entries) { |
700 | printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", | 759 | printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", |
701 | pg_start,intel_private.gtt_entries); | 760 | pg_start, intel_private.gtt_entries); |
702 | 761 | ||
703 | printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n"); | 762 | printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n"); |
704 | goto out_err; | 763 | goto out_err; |
705 | } | 764 | } |
706 | 765 | ||
@@ -738,8 +797,8 @@ out_err: | |||
738 | return ret; | 797 | return ret; |
739 | } | 798 | } |
740 | 799 | ||
741 | static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start, | 800 | static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start, |
742 | int type) | 801 | int type) |
743 | { | 802 | { |
744 | int i; | 803 | int i; |
745 | 804 | ||
@@ -747,7 +806,7 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start, | |||
747 | return 0; | 806 | return 0; |
748 | 807 | ||
749 | if (pg_start < intel_private.gtt_entries) { | 808 | if (pg_start < intel_private.gtt_entries) { |
750 | printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); | 809 | printk(KERN_INFO PFX "Trying to disable local/stolen memory\n"); |
751 | return -EINVAL; | 810 | return -EINVAL; |
752 | } | 811 | } |
753 | 812 | ||
@@ -760,7 +819,7 @@ static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start, | |||
760 | return 0; | 819 | return 0; |
761 | } | 820 | } |
762 | 821 | ||
763 | static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) | 822 | static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count, int type) |
764 | { | 823 | { |
765 | if (type == AGP_PHYS_MEMORY) | 824 | if (type == AGP_PHYS_MEMORY) |
766 | return alloc_agpphysmem_i8xx(pg_count, type); | 825 | return alloc_agpphysmem_i8xx(pg_count, type); |
@@ -768,6 +827,95 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type) | |||
768 | return NULL; | 827 | return NULL; |
769 | } | 828 | } |
770 | 829 | ||
830 | static int intel_alloc_chipset_flush_resource(void) | ||
831 | { | ||
832 | int ret; | ||
833 | ret = pci_bus_alloc_resource(agp_bridge->dev->bus, &intel_private.ifp_resource, PAGE_SIZE, | ||
834 | PAGE_SIZE, PCIBIOS_MIN_MEM, 0, | ||
835 | pcibios_align_resource, agp_bridge->dev); | ||
836 | |||
837 | return ret; | ||
838 | } | ||
839 | |||
840 | static void intel_i915_setup_chipset_flush(void) | ||
841 | { | ||
842 | int ret; | ||
843 | u32 temp; | ||
844 | |||
845 | pci_read_config_dword(agp_bridge->dev, I915_IFPADDR, &temp); | ||
846 | if (!(temp & 0x1)) { | ||
847 | intel_alloc_chipset_flush_resource(); | ||
848 | intel_private.resource_valid = 1; | ||
849 | pci_write_config_dword(agp_bridge->dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | ||
850 | } else { | ||
851 | temp &= ~1; | ||
852 | |||
853 | intel_private.resource_valid = 1; | ||
854 | intel_private.ifp_resource.start = temp; | ||
855 | intel_private.ifp_resource.end = temp + PAGE_SIZE; | ||
856 | ret = request_resource(&iomem_resource, &intel_private.ifp_resource); | ||
857 | /* some BIOSes reserve this area in a pnp some don't */ | ||
858 | if (ret) | ||
859 | intel_private.resource_valid = 0; | ||
860 | } | ||
861 | } | ||
862 | |||
863 | static void intel_i965_g33_setup_chipset_flush(void) | ||
864 | { | ||
865 | u32 temp_hi, temp_lo; | ||
866 | int ret; | ||
867 | |||
868 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR + 4, &temp_hi); | ||
869 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR, &temp_lo); | ||
870 | |||
871 | if (!(temp_lo & 0x1)) { | ||
872 | |||
873 | intel_alloc_chipset_flush_resource(); | ||
874 | |||
875 | intel_private.resource_valid = 1; | ||
876 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR + 4, | ||
877 | upper_32_bits(intel_private.ifp_resource.start)); | ||
878 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | ||
879 | } else { | ||
880 | u64 l64; | ||
881 | |||
882 | temp_lo &= ~0x1; | ||
883 | l64 = ((u64)temp_hi << 32) | temp_lo; | ||
884 | |||
885 | intel_private.resource_valid = 1; | ||
886 | intel_private.ifp_resource.start = l64; | ||
887 | intel_private.ifp_resource.end = l64 + PAGE_SIZE; | ||
888 | ret = request_resource(&iomem_resource, &intel_private.ifp_resource); | ||
889 | /* some BIOSes reserve this area in a pnp some don't */ | ||
890 | if (ret) | ||
891 | intel_private.resource_valid = 0; | ||
892 | } | ||
893 | } | ||
894 | |||
895 | static void intel_i9xx_setup_flush(void) | ||
896 | { | ||
897 | /* return if already configured */ | ||
898 | if (intel_private.ifp_resource.start) | ||
899 | return; | ||
900 | |||
901 | /* setup a resource for this object */ | ||
902 | intel_private.ifp_resource.name = "Intel Flush Page"; | ||
903 | intel_private.ifp_resource.flags = IORESOURCE_MEM; | ||
904 | |||
905 | /* Setup chipset flush for 915 */ | ||
906 | if (IS_I965 || IS_G33) { | ||
907 | intel_i965_g33_setup_chipset_flush(); | ||
908 | } else { | ||
909 | intel_i915_setup_chipset_flush(); | ||
910 | } | ||
911 | |||
912 | if (intel_private.ifp_resource.start) { | ||
913 | intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE); | ||
914 | if (!intel_private.i9xx_flush_page) | ||
915 | printk(KERN_INFO "unable to ioremap flush page - no chipset flushing"); | ||
916 | } | ||
917 | } | ||
918 | |||
771 | static int intel_i915_configure(void) | 919 | static int intel_i915_configure(void) |
772 | { | 920 | { |
773 | struct aper_size_info_fixed *current_size; | 921 | struct aper_size_info_fixed *current_size; |
@@ -781,9 +929,9 @@ static int intel_i915_configure(void) | |||
781 | 929 | ||
782 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | 930 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); |
783 | 931 | ||
784 | pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); | 932 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); |
785 | gmch_ctrl |= I830_GMCH_ENABLED; | 933 | gmch_ctrl |= I830_GMCH_ENABLED; |
786 | pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl); | 934 | pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl); |
787 | 935 | ||
788 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); | 936 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); |
789 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | 937 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ |
@@ -796,19 +944,34 @@ static int intel_i915_configure(void) | |||
796 | } | 944 | } |
797 | 945 | ||
798 | global_cache_flush(); | 946 | global_cache_flush(); |
947 | |||
948 | intel_i9xx_setup_flush(); | ||
949 | |||
799 | return 0; | 950 | return 0; |
800 | } | 951 | } |
801 | 952 | ||
802 | static void intel_i915_cleanup(void) | 953 | static void intel_i915_cleanup(void) |
803 | { | 954 | { |
955 | if (intel_private.i9xx_flush_page) | ||
956 | iounmap(intel_private.i9xx_flush_page); | ||
957 | if (intel_private.resource_valid) | ||
958 | release_resource(&intel_private.ifp_resource); | ||
959 | intel_private.ifp_resource.start = 0; | ||
960 | intel_private.resource_valid = 0; | ||
804 | iounmap(intel_private.gtt); | 961 | iounmap(intel_private.gtt); |
805 | iounmap(intel_private.registers); | 962 | iounmap(intel_private.registers); |
806 | } | 963 | } |
807 | 964 | ||
808 | static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start, | 965 | static void intel_i915_chipset_flush(struct agp_bridge_data *bridge) |
809 | int type) | ||
810 | { | 966 | { |
811 | int i,j,num_entries; | 967 | if (intel_private.i9xx_flush_page) |
968 | writel(1, intel_private.i9xx_flush_page); | ||
969 | } | ||
970 | |||
971 | static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | ||
972 | int type) | ||
973 | { | ||
974 | int i, j, num_entries; | ||
812 | void *temp; | 975 | void *temp; |
813 | int ret = -EINVAL; | 976 | int ret = -EINVAL; |
814 | int mask_type; | 977 | int mask_type; |
@@ -820,10 +983,10 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start, | |||
820 | num_entries = A_SIZE_FIX(temp)->num_entries; | 983 | num_entries = A_SIZE_FIX(temp)->num_entries; |
821 | 984 | ||
822 | if (pg_start < intel_private.gtt_entries) { | 985 | if (pg_start < intel_private.gtt_entries) { |
823 | printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", | 986 | printk(KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_private.gtt_entries == 0x%.8x\n", |
824 | pg_start,intel_private.gtt_entries); | 987 | pg_start, intel_private.gtt_entries); |
825 | 988 | ||
826 | printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n"); | 989 | printk(KERN_INFO PFX "Trying to insert into local/stolen memory\n"); |
827 | goto out_err; | 990 | goto out_err; |
828 | } | 991 | } |
829 | 992 | ||
@@ -861,8 +1024,8 @@ static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start, | |||
861 | return ret; | 1024 | return ret; |
862 | } | 1025 | } |
863 | 1026 | ||
864 | static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start, | 1027 | static int intel_i915_remove_entries(struct agp_memory *mem, off_t pg_start, |
865 | int type) | 1028 | int type) |
866 | { | 1029 | { |
867 | int i; | 1030 | int i; |
868 | 1031 | ||
@@ -870,13 +1033,13 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start, | |||
870 | return 0; | 1033 | return 0; |
871 | 1034 | ||
872 | if (pg_start < intel_private.gtt_entries) { | 1035 | if (pg_start < intel_private.gtt_entries) { |
873 | printk (KERN_INFO PFX "Trying to disable local/stolen memory\n"); | 1036 | printk(KERN_INFO PFX "Trying to disable local/stolen memory\n"); |
874 | return -EINVAL; | 1037 | return -EINVAL; |
875 | } | 1038 | } |
876 | 1039 | ||
877 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 1040 | for (i = pg_start; i < (mem->page_count + pg_start); i++) |
878 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | 1041 | writel(agp_bridge->scratch_page, intel_private.gtt+i); |
879 | } | 1042 | |
880 | readl(intel_private.gtt+i-1); | 1043 | readl(intel_private.gtt+i-1); |
881 | 1044 | ||
882 | agp_bridge->driver->tlb_flush(mem); | 1045 | agp_bridge->driver->tlb_flush(mem); |
@@ -923,7 +1086,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
923 | agp_bridge->gatt_table_real = NULL; | 1086 | agp_bridge->gatt_table_real = NULL; |
924 | 1087 | ||
925 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | 1088 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); |
926 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2); | 1089 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); |
927 | 1090 | ||
928 | if (IS_G33) | 1091 | if (IS_G33) |
929 | gtt_map_size = 1024 * 1024; /* 1M on G33 */ | 1092 | gtt_map_size = 1024 * 1024; /* 1M on G33 */ |
@@ -933,7 +1096,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
933 | 1096 | ||
934 | temp &= 0xfff80000; | 1097 | temp &= 0xfff80000; |
935 | 1098 | ||
936 | intel_private.registers = ioremap(temp,128 * 4096); | 1099 | intel_private.registers = ioremap(temp, 128 * 4096); |
937 | if (!intel_private.registers) { | 1100 | if (!intel_private.registers) { |
938 | iounmap(intel_private.gtt); | 1101 | iounmap(intel_private.gtt); |
939 | return -ENOMEM; | 1102 | return -ENOMEM; |
@@ -980,6 +1143,7 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) | |||
980 | struct aper_size_info_fixed *size; | 1143 | struct aper_size_info_fixed *size; |
981 | int num_entries; | 1144 | int num_entries; |
982 | u32 temp; | 1145 | u32 temp; |
1146 | int gtt_offset, gtt_size; | ||
983 | 1147 | ||
984 | size = agp_bridge->current_size; | 1148 | size = agp_bridge->current_size; |
985 | page_order = size->page_order; | 1149 | page_order = size->page_order; |
@@ -989,13 +1153,18 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) | |||
989 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | 1153 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); |
990 | 1154 | ||
991 | temp &= 0xfff00000; | 1155 | temp &= 0xfff00000; |
992 | intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); | ||
993 | 1156 | ||
994 | if (!intel_private.gtt) | 1157 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB) |
995 | return -ENOMEM; | 1158 | gtt_offset = gtt_size = MB(2); |
1159 | else | ||
1160 | gtt_offset = gtt_size = KB(512); | ||
1161 | |||
1162 | intel_private.gtt = ioremap((temp + gtt_offset) , gtt_size); | ||
996 | 1163 | ||
1164 | if (!intel_private.gtt) | ||
1165 | return -ENOMEM; | ||
997 | 1166 | ||
998 | intel_private.registers = ioremap(temp,128 * 4096); | 1167 | intel_private.registers = ioremap(temp, 128 * 4096); |
999 | if (!intel_private.registers) { | 1168 | if (!intel_private.registers) { |
1000 | iounmap(intel_private.gtt); | 1169 | iounmap(intel_private.gtt); |
1001 | return -ENOMEM; | 1170 | return -ENOMEM; |
@@ -1154,7 +1323,7 @@ static int intel_815_configure(void) | |||
1154 | /* the Intel 815 chipset spec. says that bits 29-31 in the | 1323 | /* the Intel 815 chipset spec. says that bits 29-31 in the |
1155 | * ATTBASE register are reserved -> try not to write them */ | 1324 | * ATTBASE register are reserved -> try not to write them */ |
1156 | if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) { | 1325 | if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) { |
1157 | printk (KERN_EMERG PFX "gatt bus addr too high"); | 1326 | printk(KERN_EMERG PFX "gatt bus addr too high"); |
1158 | return -EINVAL; | 1327 | return -EINVAL; |
1159 | } | 1328 | } |
1160 | 1329 | ||
@@ -1296,6 +1465,8 @@ static int intel_845_configure(void) | |||
1296 | pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); | 1465 | pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1)); |
1297 | /* clear any possible error conditions */ | 1466 | /* clear any possible error conditions */ |
1298 | pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); | 1467 | pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); |
1468 | |||
1469 | intel_i830_setup_flush(); | ||
1299 | return 0; | 1470 | return 0; |
1300 | } | 1471 | } |
1301 | 1472 | ||
@@ -1552,6 +1723,7 @@ static const struct agp_bridge_driver intel_830_driver = { | |||
1552 | .agp_alloc_page = agp_generic_alloc_page, | 1723 | .agp_alloc_page = agp_generic_alloc_page, |
1553 | .agp_destroy_page = agp_generic_destroy_page, | 1724 | .agp_destroy_page = agp_generic_destroy_page, |
1554 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1725 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1726 | .chipset_flush = intel_i830_chipset_flush, | ||
1555 | }; | 1727 | }; |
1556 | 1728 | ||
1557 | static const struct agp_bridge_driver intel_820_driver = { | 1729 | static const struct agp_bridge_driver intel_820_driver = { |
@@ -1648,6 +1820,7 @@ static const struct agp_bridge_driver intel_845_driver = { | |||
1648 | .agp_alloc_page = agp_generic_alloc_page, | 1820 | .agp_alloc_page = agp_generic_alloc_page, |
1649 | .agp_destroy_page = agp_generic_destroy_page, | 1821 | .agp_destroy_page = agp_generic_destroy_page, |
1650 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1822 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1823 | .chipset_flush = intel_i830_chipset_flush, | ||
1651 | }; | 1824 | }; |
1652 | 1825 | ||
1653 | static const struct agp_bridge_driver intel_850_driver = { | 1826 | static const struct agp_bridge_driver intel_850_driver = { |
@@ -1721,6 +1894,7 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
1721 | .agp_alloc_page = agp_generic_alloc_page, | 1894 | .agp_alloc_page = agp_generic_alloc_page, |
1722 | .agp_destroy_page = agp_generic_destroy_page, | 1895 | .agp_destroy_page = agp_generic_destroy_page, |
1723 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1896 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1897 | .chipset_flush = intel_i915_chipset_flush, | ||
1724 | }; | 1898 | }; |
1725 | 1899 | ||
1726 | static const struct agp_bridge_driver intel_i965_driver = { | 1900 | static const struct agp_bridge_driver intel_i965_driver = { |
@@ -1746,6 +1920,7 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
1746 | .agp_alloc_page = agp_generic_alloc_page, | 1920 | .agp_alloc_page = agp_generic_alloc_page, |
1747 | .agp_destroy_page = agp_generic_destroy_page, | 1921 | .agp_destroy_page = agp_generic_destroy_page, |
1748 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1922 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1923 | .chipset_flush = intel_i915_chipset_flush, | ||
1749 | }; | 1924 | }; |
1750 | 1925 | ||
1751 | static const struct agp_bridge_driver intel_7505_driver = { | 1926 | static const struct agp_bridge_driver intel_7505_driver = { |
@@ -1795,6 +1970,7 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
1795 | .agp_alloc_page = agp_generic_alloc_page, | 1970 | .agp_alloc_page = agp_generic_alloc_page, |
1796 | .agp_destroy_page = agp_generic_destroy_page, | 1971 | .agp_destroy_page = agp_generic_destroy_page, |
1797 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1972 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
1973 | .chipset_flush = intel_i915_chipset_flush, | ||
1798 | }; | 1974 | }; |
1799 | 1975 | ||
1800 | static int find_gmch(u16 device) | 1976 | static int find_gmch(u16 device) |
@@ -1804,7 +1980,7 @@ static int find_gmch(u16 device) | |||
1804 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); | 1980 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); |
1805 | if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) { | 1981 | if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) { |
1806 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, | 1982 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, |
1807 | device, gmch_device); | 1983 | device, gmch_device); |
1808 | } | 1984 | } |
1809 | 1985 | ||
1810 | if (!gmch_device) | 1986 | if (!gmch_device) |
@@ -1867,7 +2043,7 @@ static const struct intel_driver_description { | |||
1867 | NULL, &intel_915_driver }, | 2043 | NULL, &intel_915_driver }, |
1868 | { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ", | 2044 | { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ", |
1869 | NULL, &intel_i965_driver }, | 2045 | NULL, &intel_i965_driver }, |
1870 | { PCI_DEVICE_ID_INTEL_82965G_1_HB, PCI_DEVICE_ID_INTEL_82965G_1_IG, 0, "965G", | 2046 | { PCI_DEVICE_ID_INTEL_82G35_HB, PCI_DEVICE_ID_INTEL_82G35_IG, 0, "G35", |
1871 | NULL, &intel_i965_driver }, | 2047 | NULL, &intel_i965_driver }, |
1872 | { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, 0, "965Q", | 2048 | { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, 0, "965Q", |
1873 | NULL, &intel_i965_driver }, | 2049 | NULL, &intel_i965_driver }, |
@@ -1885,6 +2061,8 @@ static const struct intel_driver_description { | |||
1885 | NULL, &intel_g33_driver }, | 2061 | NULL, &intel_g33_driver }, |
1886 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", | 2062 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", |
1887 | NULL, &intel_g33_driver }, | 2063 | NULL, &intel_g33_driver }, |
2064 | { PCI_DEVICE_ID_INTEL_IGD_HB, PCI_DEVICE_ID_INTEL_IGD_IG, 0, | ||
2065 | "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, | ||
1888 | { 0, 0, 0, NULL, NULL, NULL } | 2066 | { 0, 0, 0, NULL, NULL, NULL } |
1889 | }; | 2067 | }; |
1890 | 2068 | ||
@@ -1924,7 +2102,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
1924 | if (intel_agp_chipsets[i].name == NULL) { | 2102 | if (intel_agp_chipsets[i].name == NULL) { |
1925 | if (cap_ptr) | 2103 | if (cap_ptr) |
1926 | printk(KERN_WARNING PFX "Unsupported Intel chipset" | 2104 | printk(KERN_WARNING PFX "Unsupported Intel chipset" |
1927 | "(device id: %04x)\n", pdev->device); | 2105 | "(device id: %04x)\n", pdev->device); |
1928 | agp_put_bridge(bridge); | 2106 | agp_put_bridge(bridge); |
1929 | return -ENODEV; | 2107 | return -ENODEV; |
1930 | } | 2108 | } |
@@ -1937,7 +2115,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
1937 | intel_agp_chipsets[i].gmch_chip_id); | 2115 | intel_agp_chipsets[i].gmch_chip_id); |
1938 | agp_put_bridge(bridge); | 2116 | agp_put_bridge(bridge); |
1939 | return -ENODEV; | 2117 | return -ENODEV; |
1940 | } | 2118 | } |
1941 | 2119 | ||
1942 | bridge->dev = pdev; | 2120 | bridge->dev = pdev; |
1943 | bridge->capndx = cap_ptr; | 2121 | bridge->capndx = cap_ptr; |
@@ -2067,7 +2245,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2067 | ID(PCI_DEVICE_ID_INTEL_82945GM_HB), | 2245 | ID(PCI_DEVICE_ID_INTEL_82945GM_HB), |
2068 | ID(PCI_DEVICE_ID_INTEL_82945GME_HB), | 2246 | ID(PCI_DEVICE_ID_INTEL_82945GME_HB), |
2069 | ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), | 2247 | ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), |
2070 | ID(PCI_DEVICE_ID_INTEL_82965G_1_HB), | 2248 | ID(PCI_DEVICE_ID_INTEL_82G35_HB), |
2071 | ID(PCI_DEVICE_ID_INTEL_82965Q_HB), | 2249 | ID(PCI_DEVICE_ID_INTEL_82965Q_HB), |
2072 | ID(PCI_DEVICE_ID_INTEL_82965G_HB), | 2250 | ID(PCI_DEVICE_ID_INTEL_82965G_HB), |
2073 | ID(PCI_DEVICE_ID_INTEL_82965GM_HB), | 2251 | ID(PCI_DEVICE_ID_INTEL_82965GM_HB), |
@@ -2075,6 +2253,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2075 | ID(PCI_DEVICE_ID_INTEL_G33_HB), | 2253 | ID(PCI_DEVICE_ID_INTEL_G33_HB), |
2076 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), | 2254 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), |
2077 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), | 2255 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), |
2256 | ID(PCI_DEVICE_ID_INTEL_IGD_HB), | ||
2078 | { } | 2257 | { } |
2079 | }; | 2258 | }; |
2080 | 2259 | ||