From: Dave Airlie <airlied@redhat.com> Date: Fri, 3 Oct 2008 15:27:18 +1000 Subject: [agp] add support for Intel Cantiga and Eaglelake Message-id: 1223011638.3380.23.camel@clockmaker.usersys.redhat.com O-Subject: [PATCH RHEL5.3 bz463853] Add support to Intel AGP for Intel Cantiga and Eaglelake Bugzilla: 463853 This is from Mauro originally, but I'm just passing it along. We've resolved the issue with the VM caused by the fast_gup stuff. From: Mauro Carvalho Chehab <mchehab@redhat.com> Date: Tue Sep 30 19:59:06 2008 -0400 for xf86-video-intel 2.4.2 or upper, AGP also needs to be patched. This patch is based on Intel backport of the upstream patch for 2.6.26-rc8, available at: http://www.intellinuxgraphics.org/download/IntelGfx-20080725/linux-agpgart-G45-for-2.6.24.patch Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b587f9e..ca22ca7 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -13,8 +13,8 @@ #define PCI_DEVICE_ID_INTEL_E7221_IG 0x258a #define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970 #define PCI_DEVICE_ID_INTEL_82946GZ_IG 0x2972 -#define PCI_DEVICE_ID_INTEL_82965G_1_HB 0x2980 -#define PCI_DEVICE_ID_INTEL_82965G_1_IG 0x2982 +#define PCI_DEVICE_ID_INTEL_82G35_HB 0x2980 +#define PCI_DEVICE_ID_INTEL_82G35_IG 0x2982 #define PCI_DEVICE_ID_INTEL_82965Q_HB 0x2990 #define PCI_DEVICE_ID_INTEL_82965Q_IG 0x2992 #define PCI_DEVICE_ID_INTEL_82965G_HB 0x29A0 @@ -32,12 +32,26 @@ #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 #define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40 #define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42 +#define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00 +#define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02 +#define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10 +#define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12 +#define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20 +#define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22 + +/* cover 915 and 945 variants */ +#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB) #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82G35_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB) @@ -45,6 +59,9 @@ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB) +#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB) /* Intel 815 register */ #define INTEL_815_APCONT 0x51 @@ -70,10 +87,17 @@ #define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) #define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) #define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) +#define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4) +#define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4) +#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) +#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) + + /* Intel 965G registers */ #define I965_MSAC 0x62 + /* Intel 7505 registers */ #define INTEL_I7505_APSIZE 0x74 #define INTEL_I7505_NCAPID 0x60 @@ -459,12 +483,25 @@ static void intel_i830_init_gtt_entries(void) case G33_PGETBL_SIZE_2M: size = 2048; break; + case I965_PGETBL_SIZE_1MB: + size = 1024; + break; + case I965_PGETBL_SIZE_2MB: + size = 2048; + break; + case I965_PGETBL_SIZE_1_5MB: + size = 1024 + 512; + break; default: printk(KERN_INFO PFX "Unknown page table size 0x%x, " "assuming 512KB\n", (gmch_ctrl & G33_PGETBL_SIZE_MASK)); size = 512; } size += 4; + } else if (IS_G4X) { + /* On 4 series hardware, GTT stolen is separate from graphics + * stolen, ignore it in stolen gtt entries counting */ + size = 0; } else { /* On previous hardware, the GTT size was just what was * required to map the aperture. @@ -513,42 +550,54 @@ static void intel_i830_init_gtt_entries(void) break; case I915_GMCH_GMS_STOLEN_48M: /* Check it's really I915G */ - if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || - IS_I965 || IS_G33) + if (IS_I915 || IS_I965 || IS_G33 || IS_G4X) gtt_entries = MB(48) - KB(size); else gtt_entries = 0; break; case I915_GMCH_GMS_STOLEN_64M: /* Check it's really I915G */ - if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB || - IS_I965 || IS_G33) + if (IS_I915 || IS_I965 || IS_G33 || IS_G4X) gtt_entries = MB(64) - KB(size); else gtt_entries = 0; break; case G33_GMCH_GMS_STOLEN_128M: - if (IS_G33) + if (IS_G33 || IS_I965 || IS_G4X) gtt_entries = MB(128) - KB(size); else gtt_entries = 0; break; case G33_GMCH_GMS_STOLEN_256M: - if (IS_G33) + if (IS_G33 || IS_I965 || IS_G4X) gtt_entries = MB(256) - KB(size); else gtt_entries = 0; break; + case INTEL_GMCH_GMS_STOLEN_96M: + if (IS_I965 || IS_G4X) + gtt_entries = MB(96) - KB(size); + else + gtt_entries = 0; + break; + case INTEL_GMCH_GMS_STOLEN_160M: + if (IS_I965 || IS_G4X) + gtt_entries = MB(160) - KB(size); + else + gtt_entries = 0; + break; + case INTEL_GMCH_GMS_STOLEN_224M: + if (IS_I965 || IS_G4X) + gtt_entries = MB(224) - KB(size); + else + gtt_entries = 0; + break; + case INTEL_GMCH_GMS_STOLEN_352M: + if (IS_I965 || IS_G4X) + gtt_entries = MB(352) - KB(size); + else + gtt_entries = 0; + break; default: gtt_entries = 0; break; @@ -928,52 +977,65 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, return addr | bridge->driver->masks[type].mask; } +static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) +{ + switch (agp_bridge->dev->device) { + case PCI_DEVICE_ID_INTEL_IGD_HB: + case PCI_DEVICE_ID_INTEL_IGD_E_HB: + case PCI_DEVICE_ID_INTEL_Q45_HB: + case PCI_DEVICE_ID_INTEL_G45_HB: + *gtt_offset = *gtt_size = MB(2); + break; + default: + *gtt_offset = *gtt_size = KB(512); + } +} + /* The intel i965 automatically initializes the agp aperture during POST. + * Use the memory already set aside for in the GTT. + */ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) { - int page_order; - struct aper_size_info_fixed *size; - int num_entries; - u32 temp; - int gtt_offset, gtt_size; - - size = agp_bridge->current_size; - page_order = size->page_order; - num_entries = size->num_entries; - agp_bridge->gatt_table_real = NULL; - - pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp); - - temp &= 0xfff00000; + int page_order; + struct aper_size_info_fixed *size; + int num_entries; + u32 temp; + int gtt_offset, gtt_size; - if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB) - gtt_offset = gtt_size = MB(2); - else - gtt_offset = gtt_size = KB(512); + size = agp_bridge->current_size; + page_order = size->page_order; + num_entries = size->num_entries; + agp_bridge->gatt_table_real = NULL; - intel_i830_private.gtt = ioremap((temp + gtt_offset), gtt_size); - if (!intel_i830_private.gtt) - return -ENOMEM; + pci_read_config_dword(intel_i830_private.i830_dev, I915_MMADDR, &temp); + temp &= 0xfff00000; - intel_i830_private.registers = ioremap(temp,128 * 4096); - if (!intel_i830_private.registers) - return -ENOMEM; + intel_i965_get_gtt_range(>t_offset, >t_size); - temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000; - global_cache_flush(); /* FIXME: ? */ + intel_i830_private.gtt = ioremap((temp + gtt_offset), gtt_size); - /* we have to call this as early as possible after the MMIO base address is known */ - intel_i830_init_gtt_entries(); + if (!intel_i830_private.gtt) + return -ENOMEM; - agp_bridge->gatt_table = NULL; + intel_i830_private.registers = ioremap(temp,128 * 4096); + if (!intel_i830_private.registers) { + iounmap(intel_i830_private.gtt); + return -ENOMEM; + } - agp_bridge->gatt_bus_addr = temp; + temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000; + global_cache_flush(); /* FIXME: ? */ - return 0; + /* we have to call this as early as possible after the MMIO base address is known */ + intel_i830_init_gtt_entries(); + + agp_bridge->gatt_table = NULL; + + agp_bridge->gatt_bus_addr = temp; + + return 0; } @@ -1937,10 +1999,10 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } else bridge->driver = NULL; break; - case PCI_DEVICE_ID_INTEL_82965G_1_HB: - if (find_i830(PCI_DEVICE_ID_INTEL_82965G_1_IG)) { + case PCI_DEVICE_ID_INTEL_82G35_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_82G35_IG)) { bridge->driver = &intel_i965_driver; - name = "965G"; + name = "G35"; } else bridge->driver = NULL; break; @@ -1951,13 +2013,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } else bridge->driver = NULL; break; - case PCI_DEVICE_ID_INTEL_82965G_HB: - if (find_i830(PCI_DEVICE_ID_INTEL_82965G_IG)) { - bridge->driver = &intel_i965_driver; - name = "965G"; - } else - bridge->driver = NULL; - break; case PCI_DEVICE_ID_INTEL_82965GM_HB: if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG)) { bridge->driver = &intel_i965_driver; @@ -1993,6 +2048,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } else bridge->driver = NULL; break; + case PCI_DEVICE_ID_INTEL_7505_0: + bridge->driver = &intel_7505_driver; + name = "E7505"; + break; + case PCI_DEVICE_ID_INTEL_7205_0: + bridge->driver = &intel_7505_driver; + name = "E7205"; + break; case PCI_DEVICE_ID_INTEL_IGD_HB: if (find_i830(PCI_DEVICE_ID_INTEL_IGD_IG)) { bridge->driver = &intel_i965_driver; @@ -2000,14 +2063,26 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } else bridge->driver = NULL; break; - - case PCI_DEVICE_ID_INTEL_7505_0: - bridge->driver = &intel_7505_driver; - name = "E7505"; + case PCI_DEVICE_ID_INTEL_IGD_E_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_IGD_E_IG)) { + bridge->driver = &intel_i965_driver; + name = "Intel Integrated Graphics Device"; + } else + bridge->driver = NULL; break; - case PCI_DEVICE_ID_INTEL_7205_0: - bridge->driver = &intel_7505_driver; - name = "E7205"; + case PCI_DEVICE_ID_INTEL_Q45_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_Q45_IG)) { + bridge->driver = &intel_i965_driver; + name = "Q45/Q43"; + } else + bridge->driver = NULL; + break; + case PCI_DEVICE_ID_INTEL_G45_HB: + if (find_i830(PCI_DEVICE_ID_INTEL_G45_IG)) { + bridge->driver = &intel_i965_driver; + name = "G45/G43"; + } else + bridge->driver = NULL; break; default: if (cap_ptr) @@ -2166,7 +2241,7 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_82945GM_HB), ID(PCI_DEVICE_ID_INTEL_82945GME_HB), ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), - ID(PCI_DEVICE_ID_INTEL_82965G_1_HB), + ID(PCI_DEVICE_ID_INTEL_82G35_HB), ID(PCI_DEVICE_ID_INTEL_82965Q_HB), ID(PCI_DEVICE_ID_INTEL_82965G_HB), ID(PCI_DEVICE_ID_INTEL_82965GM_HB), @@ -2175,6 +2250,9 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_Q35_HB), ID(PCI_DEVICE_ID_INTEL_Q33_HB), ID(PCI_DEVICE_ID_INTEL_IGD_HB), + ID(PCI_DEVICE_ID_INTEL_IGD_E_HB), + ID(PCI_DEVICE_ID_INTEL_Q45_HB), + ID(PCI_DEVICE_ID_INTEL_G45_HB), { } };