aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-12-19 15:57:24 -0500
committerDave Jones <davej@redhat.com>2006-12-22 23:12:22 -0500
commitc41e0deb50c44f9d119c2268f1be05e6a6bb5772 (patch)
tree67575d57e0a3699391a87215a0b61a3c6320ca91 /drivers/char/agp
parent5aa80c72263904f1e52eee8ed8cb75887b1d1dc3 (diff)
[AGPGART] fix detection of aperture size versus GTT size on G965
On the G965, the GTT size may be larger than is required to cover the aperture. (In fact, on all hardware we've seen, the GTT is 512KB to the aperture's 256MB). A previous commit forced the aperture size to 512MB on G965 to match GTT, which would likely result in hangs at best if users tried to rely on agpgart's aperture size information. Instead, we use the resource length for the aperture size and the system's reported GTT size when available for the GTT size. Because the MSAC registers which had been read for aperture size detection on i9xx chips just cause a change in the resource size, we can use generic code for aperture detection on all i9xx. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/char/agp')
-rw-r--r--drivers/char/agp/agp.h4
-rw-r--r--drivers/char/agp/intel-agp.c110
2 files changed, 62 insertions, 52 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 8b3317fd46c9..1d59e2a5b9aa 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -225,6 +225,10 @@ struct agp_bridge_data {
225#define I810_GMS_DISABLE 0x00000000 225#define I810_GMS_DISABLE 0x00000000
226#define I810_PGETBL_CTL 0x2020 226#define I810_PGETBL_CTL 0x2020
227#define I810_PGETBL_ENABLED 0x00000001 227#define I810_PGETBL_ENABLED 0x00000001
228#define I965_PGETBL_SIZE_MASK 0x0000000e
229#define I965_PGETBL_SIZE_512KB (0 << 1)
230#define I965_PGETBL_SIZE_256KB (1 << 1)
231#define I965_PGETBL_SIZE_128KB (2 << 1)
228#define I810_DRAM_CTL 0x3000 232#define I810_DRAM_CTL 0x3000
229#define I810_DRAM_ROW_0 0x00000001 233#define I810_DRAM_ROW_0 0x00000001
230#define I810_DRAM_ROW_0_SDRAM 0x00000001 234#define I810_DRAM_ROW_0_SDRAM 0x00000001
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 029d7f697567..ccb8018b831f 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -382,6 +382,11 @@ static struct _intel_i830_private {
382 struct pci_dev *i830_dev; /* device one */ 382 struct pci_dev *i830_dev; /* device one */
383 volatile u8 __iomem *registers; 383 volatile u8 __iomem *registers;
384 volatile u32 __iomem *gtt; /* I915G */ 384 volatile u32 __iomem *gtt; /* I915G */
385 /* gtt_entries is the number of gtt entries that are already mapped
386 * to stolen memory. Stolen memory is larger than the memory mapped
387 * through gtt_entries, as it includes some reserved space for the BIOS
388 * popup and for the GTT.
389 */
385 int gtt_entries; 390 int gtt_entries;
386} intel_i830_private; 391} intel_i830_private;
387 392
@@ -392,14 +397,41 @@ static void intel_i830_init_gtt_entries(void)
392 u8 rdct; 397 u8 rdct;
393 int local = 0; 398 int local = 0;
394 static const int ddt[4] = { 0, 16, 32, 64 }; 399 static const int ddt[4] = { 0, 16, 32, 64 };
395 int size; 400 int size; /* reserved space (in kb) at the top of stolen memory */
396 401
397 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); 402 pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
398 403
399 /* We obtain the size of the GTT, which is also stored (for some 404 if (IS_I965) {
400 * reason) at the top of stolen memory. Then we add 4KB to that 405 u32 pgetbl_ctl;
401 * for the video BIOS popup, which is also stored in there. */ 406
402 size = agp_bridge->driver->fetch_size() + 4; 407 pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
408 &pgetbl_ctl);
409 /* The 965 has a field telling us the size of the GTT,
410 * which may be larger than what is necessary to map the
411 * aperture.
412 */
413 switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
414 case I965_PGETBL_SIZE_128KB:
415 size = 128;
416 break;
417 case I965_PGETBL_SIZE_256KB:
418 size = 256;
419 break;
420 case I965_PGETBL_SIZE_512KB:
421 size = 512;
422 break;
423 default:
424 printk(KERN_INFO PFX "Unknown page table size, "
425 "assuming 512KB\n");
426 size = 512;
427 }
428 size += 4; /* add in BIOS popup space */
429 } else {
430 /* On previous hardware, the GTT size was just what was
431 * required to map the aperture.
432 */
433 size = agp_bridge->driver->fetch_size() + 4;
434 }
403 435
404 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || 436 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
405 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { 437 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
@@ -765,22 +797,27 @@ static int intel_i915_remove_entries(struct agp_memory *mem,off_t pg_start,
765 return 0; 797 return 0;
766} 798}
767 799
768static int intel_i915_fetch_size(void) 800/* Return the aperture size by just checking the resource length. The effect
801 * described in the spec of the MSAC registers is just changing of the
802 * resource size.
803 */
804static int intel_i9xx_fetch_size(void)
769{ 805{
770 struct aper_size_info_fixed *values; 806 int num_sizes = sizeof(intel_i830_sizes) / sizeof(*intel_i830_sizes);
771 u32 temp, offset; 807 int aper_size; /* size in megabytes */
808 int i;
772 809
773#define I915_256MB_ADDRESS_MASK (1<<27) 810 aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
774 811
775 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); 812 for (i = 0; i < num_sizes; i++) {
813 if (aper_size == intel_i830_sizes[i].size) {
814 agp_bridge->current_size = intel_i830_sizes + i;
815 agp_bridge->previous_size = agp_bridge->current_size;
816 return aper_size;
817 }
818 }
776 819
777 pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp); 820 return 0;
778 if (temp & I915_256MB_ADDRESS_MASK)
779 offset = 0; /* 128MB aperture */
780 else
781 offset = 2; /* 256MB aperture */
782 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
783 return values[offset].size;
784} 821}
785 822
786/* The intel i915 automatically initializes the agp aperture during POST. 823/* The intel i915 automatically initializes the agp aperture during POST.
@@ -843,40 +880,9 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
843 return addr | bridge->driver->masks[type].mask; 880 return addr | bridge->driver->masks[type].mask;
844} 881}
845 882
846static int intel_i965_fetch_size(void)
847{
848 struct aper_size_info_fixed *values;
849 u32 offset = 0;
850 u8 temp;
851
852#define I965_512MB_ADDRESS_MASK (3<<1)
853
854 values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
855
856 pci_read_config_byte(intel_i830_private.i830_dev, I965_MSAC, &temp);
857 temp &= I965_512MB_ADDRESS_MASK;
858 switch (temp) {
859 case 0x00:
860 offset = 0; /* 128MB */
861 break;
862 case 0x06:
863 offset = 3; /* 512MB */
864 break;
865 default:
866 case 0x02:
867 offset = 2; /* 256MB */
868 break;
869 }
870
871 agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
872
873 /* The i965 GTT is always sized as if it had a 512kB aperture size */
874 return 512;
875}
876
877/* The intel i965 automatically initializes the agp aperture during POST. 883/* The intel i965 automatically initializes the agp aperture during POST.
878+ * Use the memory already set aside for in the GTT. 884 * Use the memory already set aside for in the GTT.
879+ */ 885 */
880static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) 886static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
881{ 887{
882 int page_order; 888 int page_order;
@@ -1596,7 +1602,7 @@ static struct agp_bridge_driver intel_915_driver = {
1596 .num_aperture_sizes = 4, 1602 .num_aperture_sizes = 4,
1597 .needs_scratch_page = TRUE, 1603 .needs_scratch_page = TRUE,
1598 .configure = intel_i915_configure, 1604 .configure = intel_i915_configure,
1599 .fetch_size = intel_i915_fetch_size, 1605 .fetch_size = intel_i9xx_fetch_size,
1600 .cleanup = intel_i915_cleanup, 1606 .cleanup = intel_i915_cleanup,
1601 .tlb_flush = intel_i810_tlbflush, 1607 .tlb_flush = intel_i810_tlbflush,
1602 .mask_memory = intel_i810_mask_memory, 1608 .mask_memory = intel_i810_mask_memory,
@@ -1620,7 +1626,7 @@ static struct agp_bridge_driver intel_i965_driver = {
1620 .num_aperture_sizes = 4, 1626 .num_aperture_sizes = 4,
1621 .needs_scratch_page = TRUE, 1627 .needs_scratch_page = TRUE,
1622 .configure = intel_i915_configure, 1628 .configure = intel_i915_configure,
1623 .fetch_size = intel_i965_fetch_size, 1629 .fetch_size = intel_i9xx_fetch_size,
1624 .cleanup = intel_i915_cleanup, 1630 .cleanup = intel_i915_cleanup,
1625 .tlb_flush = intel_i810_tlbflush, 1631 .tlb_flush = intel_i810_tlbflush,
1626 .mask_memory = intel_i965_mask_memory, 1632 .mask_memory = intel_i965_mask_memory,