intel-gtt: maximize ggtt size on platforms that support this
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 24 Sep 2010 16:25:59 +0000 (18:25 +0200)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 27 Oct 2010 22:31:07 +0000 (23:31 +0100)
On VT-d supporting platforms the GGTT is allocated in a stolen mem
section separate from graphcis stolen mem. The GMCH register contains
a bitfield specifying the size of that region. Docs suggest that this
region can only be used for GGTT and PPGTT. Hence ensure that the
PPGTT is disabled and use the complete area for the GGTT.

Unfortunately the graphics core on G33/Pineview can't cope with really
large GTTs and the BIOS usually enables the maximum of 512MB. So
don't bother with maximizing the GTT on these platforms.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/char/agp/intel-agp.h
drivers/char/agp/intel-gtt.c

index 90539df..010e3de 100644 (file)
@@ -75,6 +75,8 @@
 #define I810_GMS_DISABLE       0x00000000
 #define I810_PGETBL_CTL                0x2020
 #define I810_PGETBL_ENABLED    0x00000001
+/* Note: PGETBL_CTL2 has a different offset on G33. */
+#define I965_PGETBL_CTL2       0x20c4
 #define I965_PGETBL_SIZE_MASK  0x0000000e
 #define I965_PGETBL_SIZE_512KB (0 << 1)
 #define I965_PGETBL_SIZE_256KB (1 << 1)
 #define I965_PGETBL_SIZE_1MB   (3 << 1)
 #define I965_PGETBL_SIZE_2MB   (4 << 1)
 #define I965_PGETBL_SIZE_1_5MB (5 << 1)
-#define G33_PGETBL_SIZE_MASK    (3 << 8)
-#define G33_PGETBL_SIZE_1M      (1 << 8)
-#define G33_PGETBL_SIZE_2M      (2 << 8)
+#define G33_GMCH_SIZE_MASK     (3 << 8)
+#define G33_GMCH_SIZE_1M       (1 << 8)
+#define G33_GMCH_SIZE_2M       (2 << 8)
+#define G4x_GMCH_SIZE_MASK     (0xf << 8)
+#define G4x_GMCH_SIZE_1M       (0x1 << 8)
+#define G4x_GMCH_SIZE_2M       (0x3 << 8)
+#define G4x_GMCH_SIZE_VT_1M    (0x9 << 8)
+#define G4x_GMCH_SIZE_VT_1_5M  (0xa << 8)
+#define G4x_GMCH_SIZE_VT_2M    (0xc << 8)
 
 #define I810_DRAM_CTL          0x3000
 #define I810_DRAM_ROW_0                0x00000001
index fd3e94f..5dc1f5d 100644 (file)
@@ -642,41 +642,85 @@ static unsigned int intel_gtt_stolen_entries(void)
        return stolen_entries;
 }
 
-static unsigned int intel_gtt_total_entries(void)
+static void i965_adjust_pgetbl_size(unsigned int size_flag)
+{
+       u32 pgetbl_ctl, pgetbl_ctl2;
+
+       /* ensure that ppgtt is disabled */
+       pgetbl_ctl2 = readl(intel_private.registers+I965_PGETBL_CTL2);
+       pgetbl_ctl2 &= ~I810_PGETBL_ENABLED;
+       writel(pgetbl_ctl2, intel_private.registers+I965_PGETBL_CTL2);
+
+       /* write the new ggtt size */
+       pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
+       pgetbl_ctl &= ~I965_PGETBL_SIZE_MASK;
+       pgetbl_ctl |= size_flag;
+       writel(pgetbl_ctl, intel_private.registers+I810_PGETBL_CTL);
+}
+
+static unsigned int i965_gtt_total_entries(void)
 {
        int size;
+       u32 pgetbl_ctl;
+       u16 gmch_ctl;
 
-       if (IS_G33 || INTEL_GTT_GEN == 4 || INTEL_GTT_GEN == 5) {
-               u32 pgetbl_ctl;
-               pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
+       pci_read_config_word(intel_private.bridge_dev,
+                            I830_GMCH_CTRL, &gmch_ctl);
 
-               switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
-               case I965_PGETBL_SIZE_128KB:
-                       size = KB(128);
-                       break;
-               case I965_PGETBL_SIZE_256KB:
-                       size = KB(256);
-                       break;
-               case I965_PGETBL_SIZE_512KB:
-                       size = KB(512);
-                       break;
-               case I965_PGETBL_SIZE_1MB:
-                       size = KB(1024);
+       if (INTEL_GTT_GEN == 5) {
+               switch (gmch_ctl & G4x_GMCH_SIZE_MASK) {
+               case G4x_GMCH_SIZE_1M:
+               case G4x_GMCH_SIZE_VT_1M:
+                       i965_adjust_pgetbl_size(I965_PGETBL_SIZE_1MB);
                        break;
-               case I965_PGETBL_SIZE_2MB:
-                       size = KB(2048);
+               case G4x_GMCH_SIZE_VT_1_5M:
+                       i965_adjust_pgetbl_size(I965_PGETBL_SIZE_1_5MB);
                        break;
-               case I965_PGETBL_SIZE_1_5MB:
-                       size = KB(1024 + 512);
+               case G4x_GMCH_SIZE_2M:
+               case G4x_GMCH_SIZE_VT_2M:
+                       i965_adjust_pgetbl_size(I965_PGETBL_SIZE_2MB);
                        break;
-               default:
-                       dev_info(&intel_private.pcidev->dev,
-                                "unknown page table size, assuming 512KB\n");
-                       size = KB(512);
                }
+       }
 
-               return size/4;
-       } else if (INTEL_GTT_GEN == 6) {
+       pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL);
+
+       switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
+       case I965_PGETBL_SIZE_128KB:
+               size = KB(128);
+               break;
+       case I965_PGETBL_SIZE_256KB:
+               size = KB(256);
+               break;
+       case I965_PGETBL_SIZE_512KB:
+               size = KB(512);
+               break;
+       /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
+       case I965_PGETBL_SIZE_1MB:
+               size = KB(1024);
+               break;
+       case I965_PGETBL_SIZE_2MB:
+               size = KB(2048);
+               break;
+       case I965_PGETBL_SIZE_1_5MB:
+               size = KB(1024 + 512);
+               break;
+       default:
+               dev_info(&intel_private.pcidev->dev,
+                        "unknown page table size, assuming 512KB\n");
+               size = KB(512);
+       }
+
+       return size/4;
+}
+
+static unsigned int intel_gtt_total_entries(void)
+{
+       int size;
+
+       if (IS_G33 || INTEL_GTT_GEN == 4 || INTEL_GTT_GEN == 5)
+               return i965_gtt_total_entries();
+       else if (INTEL_GTT_GEN == 6) {
                u16 snb_gmch_ctl;
 
                pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl);