Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Intel AGPGART routines.
0003  */
0004 
0005 #include <linux/module.h>
0006 #include <linux/pci.h>
0007 #include <linux/slab.h>
0008 #include <linux/init.h>
0009 #include <linux/kernel.h>
0010 #include <linux/pagemap.h>
0011 #include <linux/agp_backend.h>
0012 #include <asm/smp.h>
0013 #include "agp.h"
0014 #include "intel-agp.h"
0015 #include <drm/intel-gtt.h>
0016 
0017 static int intel_fetch_size(void)
0018 {
0019     int i;
0020     u16 temp;
0021     struct aper_size_info_16 *values;
0022 
0023     pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
0024     values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
0025 
0026     for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
0027         if (temp == values[i].size_value) {
0028             agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
0029             agp_bridge->aperture_size_idx = i;
0030             return values[i].size;
0031         }
0032     }
0033 
0034     return 0;
0035 }
0036 
0037 static int __intel_8xx_fetch_size(u8 temp)
0038 {
0039     int i;
0040     struct aper_size_info_8 *values;
0041 
0042     values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
0043 
0044     for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
0045         if (temp == values[i].size_value) {
0046             agp_bridge->previous_size =
0047                 agp_bridge->current_size = (void *) (values + i);
0048             agp_bridge->aperture_size_idx = i;
0049             return values[i].size;
0050         }
0051     }
0052     return 0;
0053 }
0054 
0055 static int intel_8xx_fetch_size(void)
0056 {
0057     u8 temp;
0058 
0059     pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
0060     return __intel_8xx_fetch_size(temp);
0061 }
0062 
0063 static int intel_815_fetch_size(void)
0064 {
0065     u8 temp;
0066 
0067     /* Intel 815 chipsets have a _weird_ APSIZE register with only
0068      * one non-reserved bit, so mask the others out ... */
0069     pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
0070     temp &= (1 << 3);
0071 
0072     return __intel_8xx_fetch_size(temp);
0073 }
0074 
0075 static void intel_tlbflush(struct agp_memory *mem)
0076 {
0077     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
0078     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
0079 }
0080 
0081 
0082 static void intel_8xx_tlbflush(struct agp_memory *mem)
0083 {
0084     u32 temp;
0085     pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
0086     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
0087     pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
0088     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
0089 }
0090 
0091 
0092 static void intel_cleanup(void)
0093 {
0094     u16 temp;
0095     struct aper_size_info_16 *previous_size;
0096 
0097     previous_size = A_SIZE_16(agp_bridge->previous_size);
0098     pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
0099     pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
0100     pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
0101 }
0102 
0103 
0104 static void intel_8xx_cleanup(void)
0105 {
0106     u16 temp;
0107     struct aper_size_info_8 *previous_size;
0108 
0109     previous_size = A_SIZE_8(agp_bridge->previous_size);
0110     pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
0111     pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
0112     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
0113 }
0114 
0115 
0116 static int intel_configure(void)
0117 {
0118     u16 temp2;
0119     struct aper_size_info_16 *current_size;
0120 
0121     current_size = A_SIZE_16(agp_bridge->current_size);
0122 
0123     /* aperture size */
0124     pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0125 
0126     /* address to map to */
0127     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0128                             AGP_APERTURE_BAR);
0129 
0130     /* attbase - aperture base */
0131     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0132 
0133     /* agpctrl */
0134     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
0135 
0136     /* paccfg/nbxcfg */
0137     pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
0138     pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
0139             (temp2 & ~(1 << 10)) | (1 << 9));
0140     /* clear any possible error conditions */
0141     pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
0142     return 0;
0143 }
0144 
0145 static int intel_815_configure(void)
0146 {
0147     u32 addr;
0148     u8 temp2;
0149     struct aper_size_info_8 *current_size;
0150 
0151     /* attbase - aperture base */
0152     /* the Intel 815 chipset spec. says that bits 29-31 in the
0153     * ATTBASE register are reserved -> try not to write them */
0154     if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
0155         dev_emerg(&agp_bridge->dev->dev, "gatt bus addr too high");
0156         return -EINVAL;
0157     }
0158 
0159     current_size = A_SIZE_8(agp_bridge->current_size);
0160 
0161     /* aperture size */
0162     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
0163             current_size->size_value);
0164 
0165     /* address to map to */
0166     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0167                             AGP_APERTURE_BAR);
0168 
0169     pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);
0170     addr &= INTEL_815_ATTBASE_MASK;
0171     addr |= agp_bridge->gatt_bus_addr;
0172     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);
0173 
0174     /* agpctrl */
0175     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0176 
0177     /* apcont */
0178     pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);
0179     pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));
0180 
0181     /* clear any possible error conditions */
0182     /* Oddness : this chipset seems to have no ERRSTS register ! */
0183     return 0;
0184 }
0185 
0186 static void intel_820_tlbflush(struct agp_memory *mem)
0187 {
0188     return;
0189 }
0190 
0191 static void intel_820_cleanup(void)
0192 {
0193     u8 temp;
0194     struct aper_size_info_8 *previous_size;
0195 
0196     previous_size = A_SIZE_8(agp_bridge->previous_size);
0197     pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);
0198     pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR,
0199             temp & ~(1 << 1));
0200     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
0201             previous_size->size_value);
0202 }
0203 
0204 
0205 static int intel_820_configure(void)
0206 {
0207     u8 temp2;
0208     struct aper_size_info_8 *current_size;
0209 
0210     current_size = A_SIZE_8(agp_bridge->current_size);
0211 
0212     /* aperture size */
0213     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0214 
0215     /* address to map to */
0216     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0217                             AGP_APERTURE_BAR);
0218 
0219     /* attbase - aperture base */
0220     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0221 
0222     /* agpctrl */
0223     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0224 
0225     /* global enable aperture access */
0226     /* This flag is not accessed through MCHCFG register as in */
0227     /* i850 chipset. */
0228     pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);
0229     pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));
0230     /* clear any possible AGP-related error conditions */
0231     pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c);
0232     return 0;
0233 }
0234 
0235 static int intel_840_configure(void)
0236 {
0237     u16 temp2;
0238     struct aper_size_info_8 *current_size;
0239 
0240     current_size = A_SIZE_8(agp_bridge->current_size);
0241 
0242     /* aperture size */
0243     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0244 
0245     /* address to map to */
0246     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0247                             AGP_APERTURE_BAR);
0248 
0249     /* attbase - aperture base */
0250     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0251 
0252     /* agpctrl */
0253     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0254 
0255     /* mcgcfg */
0256     pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);
0257     pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
0258     /* clear any possible error conditions */
0259     pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000);
0260     return 0;
0261 }
0262 
0263 static int intel_845_configure(void)
0264 {
0265     u8 temp2;
0266     struct aper_size_info_8 *current_size;
0267 
0268     current_size = A_SIZE_8(agp_bridge->current_size);
0269 
0270     /* aperture size */
0271     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0272 
0273     if (agp_bridge->apbase_config != 0) {
0274         pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
0275                        agp_bridge->apbase_config);
0276     } else {
0277         /* address to map to */
0278         agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0279                                 AGP_APERTURE_BAR);
0280         agp_bridge->apbase_config = agp_bridge->gart_bus_addr;
0281     }
0282 
0283     /* attbase - aperture base */
0284     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0285 
0286     /* agpctrl */
0287     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0288 
0289     /* agpm */
0290     pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
0291     pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
0292     /* clear any possible error conditions */
0293     pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
0294     return 0;
0295 }
0296 
0297 static int intel_850_configure(void)
0298 {
0299     u16 temp2;
0300     struct aper_size_info_8 *current_size;
0301 
0302     current_size = A_SIZE_8(agp_bridge->current_size);
0303 
0304     /* aperture size */
0305     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0306 
0307     /* address to map to */
0308     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0309                             AGP_APERTURE_BAR);
0310 
0311     /* attbase - aperture base */
0312     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0313 
0314     /* agpctrl */
0315     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0316 
0317     /* mcgcfg */
0318     pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);
0319     pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
0320     /* clear any possible AGP-related error conditions */
0321     pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c);
0322     return 0;
0323 }
0324 
0325 static int intel_860_configure(void)
0326 {
0327     u16 temp2;
0328     struct aper_size_info_8 *current_size;
0329 
0330     current_size = A_SIZE_8(agp_bridge->current_size);
0331 
0332     /* aperture size */
0333     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0334 
0335     /* address to map to */
0336     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0337                             AGP_APERTURE_BAR);
0338 
0339     /* attbase - aperture base */
0340     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0341 
0342     /* agpctrl */
0343     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0344 
0345     /* mcgcfg */
0346     pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);
0347     pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
0348     /* clear any possible AGP-related error conditions */
0349     pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);
0350     return 0;
0351 }
0352 
0353 static int intel_830mp_configure(void)
0354 {
0355     u16 temp2;
0356     struct aper_size_info_8 *current_size;
0357 
0358     current_size = A_SIZE_8(agp_bridge->current_size);
0359 
0360     /* aperture size */
0361     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0362 
0363     /* address to map to */
0364     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0365                             AGP_APERTURE_BAR);
0366 
0367     /* attbase - aperture base */
0368     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0369 
0370     /* agpctrl */
0371     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0372 
0373     /* gmch */
0374     pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
0375     pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));
0376     /* clear any possible AGP-related error conditions */
0377     pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);
0378     return 0;
0379 }
0380 
0381 static int intel_7505_configure(void)
0382 {
0383     u16 temp2;
0384     struct aper_size_info_8 *current_size;
0385 
0386     current_size = A_SIZE_8(agp_bridge->current_size);
0387 
0388     /* aperture size */
0389     pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
0390 
0391     /* address to map to */
0392     agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
0393                             AGP_APERTURE_BAR);
0394 
0395     /* attbase - aperture base */
0396     pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
0397 
0398     /* agpctrl */
0399     pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
0400 
0401     /* mchcfg */
0402     pci_read_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, &temp2);
0403     pci_write_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, temp2 | (1 << 9));
0404 
0405     return 0;
0406 }
0407 
0408 /* Setup function */
0409 static const struct gatt_mask intel_generic_masks[] =
0410 {
0411     {.mask = 0x00000017, .type = 0}
0412 };
0413 
0414 static const struct aper_size_info_8 intel_815_sizes[2] =
0415 {
0416     {64, 16384, 4, 0},
0417     {32, 8192, 3, 8},
0418 };
0419 
0420 static const struct aper_size_info_8 intel_8xx_sizes[7] =
0421 {
0422     {256, 65536, 6, 0},
0423     {128, 32768, 5, 32},
0424     {64, 16384, 4, 48},
0425     {32, 8192, 3, 56},
0426     {16, 4096, 2, 60},
0427     {8, 2048, 1, 62},
0428     {4, 1024, 0, 63}
0429 };
0430 
0431 static const struct aper_size_info_16 intel_generic_sizes[7] =
0432 {
0433     {256, 65536, 6, 0},
0434     {128, 32768, 5, 32},
0435     {64, 16384, 4, 48},
0436     {32, 8192, 3, 56},
0437     {16, 4096, 2, 60},
0438     {8, 2048, 1, 62},
0439     {4, 1024, 0, 63}
0440 };
0441 
0442 static const struct aper_size_info_8 intel_830mp_sizes[4] =
0443 {
0444     {256, 65536, 6, 0},
0445     {128, 32768, 5, 32},
0446     {64, 16384, 4, 48},
0447     {32, 8192, 3, 56}
0448 };
0449 
0450 static const struct agp_bridge_driver intel_generic_driver = {
0451     .owner          = THIS_MODULE,
0452     .aperture_sizes     = intel_generic_sizes,
0453     .size_type      = U16_APER_SIZE,
0454     .num_aperture_sizes = 7,
0455     .needs_scratch_page = true,
0456     .configure      = intel_configure,
0457     .fetch_size     = intel_fetch_size,
0458     .cleanup        = intel_cleanup,
0459     .tlb_flush      = intel_tlbflush,
0460     .mask_memory        = agp_generic_mask_memory,
0461     .masks          = intel_generic_masks,
0462     .agp_enable     = agp_generic_enable,
0463     .cache_flush        = global_cache_flush,
0464     .create_gatt_table  = agp_generic_create_gatt_table,
0465     .free_gatt_table    = agp_generic_free_gatt_table,
0466     .insert_memory      = agp_generic_insert_memory,
0467     .remove_memory      = agp_generic_remove_memory,
0468     .alloc_by_type      = agp_generic_alloc_by_type,
0469     .free_by_type       = agp_generic_free_by_type,
0470     .agp_alloc_page     = agp_generic_alloc_page,
0471     .agp_alloc_pages        = agp_generic_alloc_pages,
0472     .agp_destroy_page   = agp_generic_destroy_page,
0473     .agp_destroy_pages      = agp_generic_destroy_pages,
0474     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0475 };
0476 
0477 static const struct agp_bridge_driver intel_815_driver = {
0478     .owner          = THIS_MODULE,
0479     .aperture_sizes     = intel_815_sizes,
0480     .size_type      = U8_APER_SIZE,
0481     .num_aperture_sizes = 2,
0482     .needs_scratch_page = true,
0483     .configure      = intel_815_configure,
0484     .fetch_size     = intel_815_fetch_size,
0485     .cleanup        = intel_8xx_cleanup,
0486     .tlb_flush      = intel_8xx_tlbflush,
0487     .mask_memory        = agp_generic_mask_memory,
0488     .masks          = intel_generic_masks,
0489     .agp_enable     = agp_generic_enable,
0490     .cache_flush        = global_cache_flush,
0491     .create_gatt_table  = agp_generic_create_gatt_table,
0492     .free_gatt_table    = agp_generic_free_gatt_table,
0493     .insert_memory      = agp_generic_insert_memory,
0494     .remove_memory      = agp_generic_remove_memory,
0495     .alloc_by_type      = agp_generic_alloc_by_type,
0496     .free_by_type       = agp_generic_free_by_type,
0497     .agp_alloc_page     = agp_generic_alloc_page,
0498     .agp_alloc_pages        = agp_generic_alloc_pages,
0499     .agp_destroy_page   = agp_generic_destroy_page,
0500     .agp_destroy_pages      = agp_generic_destroy_pages,
0501     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0502 };
0503 
0504 static const struct agp_bridge_driver intel_820_driver = {
0505     .owner          = THIS_MODULE,
0506     .aperture_sizes     = intel_8xx_sizes,
0507     .size_type      = U8_APER_SIZE,
0508     .num_aperture_sizes = 7,
0509     .needs_scratch_page = true,
0510     .configure      = intel_820_configure,
0511     .fetch_size     = intel_8xx_fetch_size,
0512     .cleanup        = intel_820_cleanup,
0513     .tlb_flush      = intel_820_tlbflush,
0514     .mask_memory        = agp_generic_mask_memory,
0515     .masks          = intel_generic_masks,
0516     .agp_enable     = agp_generic_enable,
0517     .cache_flush        = global_cache_flush,
0518     .create_gatt_table  = agp_generic_create_gatt_table,
0519     .free_gatt_table    = agp_generic_free_gatt_table,
0520     .insert_memory      = agp_generic_insert_memory,
0521     .remove_memory      = agp_generic_remove_memory,
0522     .alloc_by_type      = agp_generic_alloc_by_type,
0523     .free_by_type       = agp_generic_free_by_type,
0524     .agp_alloc_page     = agp_generic_alloc_page,
0525     .agp_alloc_pages        = agp_generic_alloc_pages,
0526     .agp_destroy_page   = agp_generic_destroy_page,
0527     .agp_destroy_pages      = agp_generic_destroy_pages,
0528     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0529 };
0530 
0531 static const struct agp_bridge_driver intel_830mp_driver = {
0532     .owner          = THIS_MODULE,
0533     .aperture_sizes     = intel_830mp_sizes,
0534     .size_type      = U8_APER_SIZE,
0535     .num_aperture_sizes = 4,
0536     .needs_scratch_page = true,
0537     .configure      = intel_830mp_configure,
0538     .fetch_size     = intel_8xx_fetch_size,
0539     .cleanup        = intel_8xx_cleanup,
0540     .tlb_flush      = intel_8xx_tlbflush,
0541     .mask_memory        = agp_generic_mask_memory,
0542     .masks          = intel_generic_masks,
0543     .agp_enable     = agp_generic_enable,
0544     .cache_flush        = global_cache_flush,
0545     .create_gatt_table  = agp_generic_create_gatt_table,
0546     .free_gatt_table    = agp_generic_free_gatt_table,
0547     .insert_memory      = agp_generic_insert_memory,
0548     .remove_memory      = agp_generic_remove_memory,
0549     .alloc_by_type      = agp_generic_alloc_by_type,
0550     .free_by_type       = agp_generic_free_by_type,
0551     .agp_alloc_page     = agp_generic_alloc_page,
0552     .agp_alloc_pages        = agp_generic_alloc_pages,
0553     .agp_destroy_page   = agp_generic_destroy_page,
0554     .agp_destroy_pages      = agp_generic_destroy_pages,
0555     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0556 };
0557 
0558 static const struct agp_bridge_driver intel_840_driver = {
0559     .owner          = THIS_MODULE,
0560     .aperture_sizes     = intel_8xx_sizes,
0561     .size_type      = U8_APER_SIZE,
0562     .num_aperture_sizes = 7,
0563     .needs_scratch_page = true,
0564     .configure      = intel_840_configure,
0565     .fetch_size     = intel_8xx_fetch_size,
0566     .cleanup        = intel_8xx_cleanup,
0567     .tlb_flush      = intel_8xx_tlbflush,
0568     .mask_memory        = agp_generic_mask_memory,
0569     .masks          = intel_generic_masks,
0570     .agp_enable     = agp_generic_enable,
0571     .cache_flush        = global_cache_flush,
0572     .create_gatt_table  = agp_generic_create_gatt_table,
0573     .free_gatt_table    = agp_generic_free_gatt_table,
0574     .insert_memory      = agp_generic_insert_memory,
0575     .remove_memory      = agp_generic_remove_memory,
0576     .alloc_by_type      = agp_generic_alloc_by_type,
0577     .free_by_type       = agp_generic_free_by_type,
0578     .agp_alloc_page     = agp_generic_alloc_page,
0579     .agp_alloc_pages        = agp_generic_alloc_pages,
0580     .agp_destroy_page   = agp_generic_destroy_page,
0581     .agp_destroy_pages      = agp_generic_destroy_pages,
0582     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0583 };
0584 
0585 static const struct agp_bridge_driver intel_845_driver = {
0586     .owner          = THIS_MODULE,
0587     .aperture_sizes     = intel_8xx_sizes,
0588     .size_type      = U8_APER_SIZE,
0589     .num_aperture_sizes = 7,
0590     .needs_scratch_page = true,
0591     .configure      = intel_845_configure,
0592     .fetch_size     = intel_8xx_fetch_size,
0593     .cleanup        = intel_8xx_cleanup,
0594     .tlb_flush      = intel_8xx_tlbflush,
0595     .mask_memory        = agp_generic_mask_memory,
0596     .masks          = intel_generic_masks,
0597     .agp_enable     = agp_generic_enable,
0598     .cache_flush        = global_cache_flush,
0599     .create_gatt_table  = agp_generic_create_gatt_table,
0600     .free_gatt_table    = agp_generic_free_gatt_table,
0601     .insert_memory      = agp_generic_insert_memory,
0602     .remove_memory      = agp_generic_remove_memory,
0603     .alloc_by_type      = agp_generic_alloc_by_type,
0604     .free_by_type       = agp_generic_free_by_type,
0605     .agp_alloc_page     = agp_generic_alloc_page,
0606     .agp_alloc_pages        = agp_generic_alloc_pages,
0607     .agp_destroy_page   = agp_generic_destroy_page,
0608     .agp_destroy_pages      = agp_generic_destroy_pages,
0609     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0610 };
0611 
0612 static const struct agp_bridge_driver intel_850_driver = {
0613     .owner          = THIS_MODULE,
0614     .aperture_sizes     = intel_8xx_sizes,
0615     .size_type      = U8_APER_SIZE,
0616     .num_aperture_sizes = 7,
0617     .needs_scratch_page = true,
0618     .configure      = intel_850_configure,
0619     .fetch_size     = intel_8xx_fetch_size,
0620     .cleanup        = intel_8xx_cleanup,
0621     .tlb_flush      = intel_8xx_tlbflush,
0622     .mask_memory        = agp_generic_mask_memory,
0623     .masks          = intel_generic_masks,
0624     .agp_enable     = agp_generic_enable,
0625     .cache_flush        = global_cache_flush,
0626     .create_gatt_table  = agp_generic_create_gatt_table,
0627     .free_gatt_table    = agp_generic_free_gatt_table,
0628     .insert_memory      = agp_generic_insert_memory,
0629     .remove_memory      = agp_generic_remove_memory,
0630     .alloc_by_type      = agp_generic_alloc_by_type,
0631     .free_by_type       = agp_generic_free_by_type,
0632     .agp_alloc_page     = agp_generic_alloc_page,
0633     .agp_alloc_pages        = agp_generic_alloc_pages,
0634     .agp_destroy_page   = agp_generic_destroy_page,
0635     .agp_destroy_pages      = agp_generic_destroy_pages,
0636     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0637 };
0638 
0639 static const struct agp_bridge_driver intel_860_driver = {
0640     .owner          = THIS_MODULE,
0641     .aperture_sizes     = intel_8xx_sizes,
0642     .size_type      = U8_APER_SIZE,
0643     .num_aperture_sizes = 7,
0644     .needs_scratch_page = true,
0645     .configure      = intel_860_configure,
0646     .fetch_size     = intel_8xx_fetch_size,
0647     .cleanup        = intel_8xx_cleanup,
0648     .tlb_flush      = intel_8xx_tlbflush,
0649     .mask_memory        = agp_generic_mask_memory,
0650     .masks          = intel_generic_masks,
0651     .agp_enable     = agp_generic_enable,
0652     .cache_flush        = global_cache_flush,
0653     .create_gatt_table  = agp_generic_create_gatt_table,
0654     .free_gatt_table    = agp_generic_free_gatt_table,
0655     .insert_memory      = agp_generic_insert_memory,
0656     .remove_memory      = agp_generic_remove_memory,
0657     .alloc_by_type      = agp_generic_alloc_by_type,
0658     .free_by_type       = agp_generic_free_by_type,
0659     .agp_alloc_page     = agp_generic_alloc_page,
0660     .agp_alloc_pages        = agp_generic_alloc_pages,
0661     .agp_destroy_page   = agp_generic_destroy_page,
0662     .agp_destroy_pages      = agp_generic_destroy_pages,
0663     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0664 };
0665 
0666 static const struct agp_bridge_driver intel_7505_driver = {
0667     .owner          = THIS_MODULE,
0668     .aperture_sizes     = intel_8xx_sizes,
0669     .size_type      = U8_APER_SIZE,
0670     .num_aperture_sizes = 7,
0671     .needs_scratch_page = true,
0672     .configure      = intel_7505_configure,
0673     .fetch_size     = intel_8xx_fetch_size,
0674     .cleanup        = intel_8xx_cleanup,
0675     .tlb_flush      = intel_8xx_tlbflush,
0676     .mask_memory        = agp_generic_mask_memory,
0677     .masks          = intel_generic_masks,
0678     .agp_enable     = agp_generic_enable,
0679     .cache_flush        = global_cache_flush,
0680     .create_gatt_table  = agp_generic_create_gatt_table,
0681     .free_gatt_table    = agp_generic_free_gatt_table,
0682     .insert_memory      = agp_generic_insert_memory,
0683     .remove_memory      = agp_generic_remove_memory,
0684     .alloc_by_type      = agp_generic_alloc_by_type,
0685     .free_by_type       = agp_generic_free_by_type,
0686     .agp_alloc_page     = agp_generic_alloc_page,
0687     .agp_alloc_pages        = agp_generic_alloc_pages,
0688     .agp_destroy_page   = agp_generic_destroy_page,
0689     .agp_destroy_pages      = agp_generic_destroy_pages,
0690     .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
0691 };
0692 
0693 /* Table to describe Intel GMCH and AGP/PCIE GART drivers.  At least one of
0694  * driver and gmch_driver must be non-null, and find_gmch will determine
0695  * which one should be used if a gmch_chip_id is present.
0696  */
0697 static const struct intel_agp_driver_description {
0698     unsigned int chip_id;
0699     char *name;
0700     const struct agp_bridge_driver *driver;
0701 } intel_agp_chipsets[] = {
0702     { PCI_DEVICE_ID_INTEL_82443LX_0, "440LX", &intel_generic_driver },
0703     { PCI_DEVICE_ID_INTEL_82443BX_0, "440BX", &intel_generic_driver },
0704     { PCI_DEVICE_ID_INTEL_82443GX_0, "440GX", &intel_generic_driver },
0705     { PCI_DEVICE_ID_INTEL_82815_MC, "i815", &intel_815_driver },
0706     { PCI_DEVICE_ID_INTEL_82820_HB, "i820", &intel_820_driver },
0707     { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver },
0708     { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver },
0709     { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver },
0710     { PCI_DEVICE_ID_INTEL_82845_HB, "i845", &intel_845_driver },
0711     { PCI_DEVICE_ID_INTEL_82845G_HB, "845G", &intel_845_driver },
0712     { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver },
0713     { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver },
0714     { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver },
0715     { PCI_DEVICE_ID_INTEL_82855GM_HB, "855GM", &intel_845_driver },
0716     { PCI_DEVICE_ID_INTEL_82860_HB, "i860", &intel_860_driver },
0717     { PCI_DEVICE_ID_INTEL_82865_HB, "865", &intel_845_driver },
0718     { PCI_DEVICE_ID_INTEL_82875_HB, "i875", &intel_845_driver },
0719     { PCI_DEVICE_ID_INTEL_7505_0, "E7505", &intel_7505_driver },
0720     { PCI_DEVICE_ID_INTEL_7205_0, "E7205", &intel_7505_driver },
0721     { 0, NULL, NULL }
0722 };
0723 
0724 static int agp_intel_probe(struct pci_dev *pdev,
0725                const struct pci_device_id *ent)
0726 {
0727     struct agp_bridge_data *bridge;
0728     u8 cap_ptr = 0;
0729     struct resource *r;
0730     int i, err;
0731 
0732     cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
0733 
0734     bridge = agp_alloc_bridge();
0735     if (!bridge)
0736         return -ENOMEM;
0737 
0738     bridge->capndx = cap_ptr;
0739 
0740     if (intel_gmch_probe(pdev, NULL, bridge))
0741         goto found_gmch;
0742 
0743     for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
0744         /* In case that multiple models of gfx chip may
0745            stand on same host bridge type, this can be
0746            sure we detect the right IGD. */
0747         if (pdev->device == intel_agp_chipsets[i].chip_id) {
0748             bridge->driver = intel_agp_chipsets[i].driver;
0749             break;
0750         }
0751     }
0752 
0753     if (!bridge->driver) {
0754         if (cap_ptr)
0755             dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n",
0756                  pdev->vendor, pdev->device);
0757         agp_put_bridge(bridge);
0758         return -ENODEV;
0759     }
0760 
0761     bridge->dev = pdev;
0762     bridge->dev_private_data = NULL;
0763 
0764     dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
0765 
0766     /*
0767     * The following fixes the case where the BIOS has "forgotten" to
0768     * provide an address range for the GART.
0769     * 20030610 - hamish@zot.org
0770     * This happens before pci_enable_device() intentionally;
0771     * calling pci_enable_device() before assigning the resource
0772     * will result in the GART being disabled on machines with such
0773     * BIOSs (the GART ends up with a BAR starting at 0, which
0774     * conflicts a lot of other devices).
0775     */
0776     r = &pdev->resource[0];
0777     if (!r->start && r->end) {
0778         if (pci_assign_resource(pdev, 0)) {
0779             dev_err(&pdev->dev, "can't assign resource 0\n");
0780             agp_put_bridge(bridge);
0781             return -ENODEV;
0782         }
0783     }
0784 
0785     /*
0786     * If the device has not been properly setup, the following will catch
0787     * the problem and should stop the system from crashing.
0788     * 20030610 - hamish@zot.org
0789     */
0790     if (pci_enable_device(pdev)) {
0791         dev_err(&pdev->dev, "can't enable PCI device\n");
0792         agp_put_bridge(bridge);
0793         return -ENODEV;
0794     }
0795 
0796     /* Fill in the mode register */
0797     if (cap_ptr) {
0798         pci_read_config_dword(pdev,
0799                 bridge->capndx+PCI_AGP_STATUS,
0800                 &bridge->mode);
0801     }
0802 
0803 found_gmch:
0804     pci_set_drvdata(pdev, bridge);
0805     err = agp_add_bridge(bridge);
0806     return err;
0807 }
0808 
0809 static void agp_intel_remove(struct pci_dev *pdev)
0810 {
0811     struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
0812 
0813     agp_remove_bridge(bridge);
0814 
0815     intel_gmch_remove();
0816 
0817     agp_put_bridge(bridge);
0818 }
0819 
0820 #ifdef CONFIG_PM
0821 static int agp_intel_resume(struct pci_dev *pdev)
0822 {
0823     struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
0824 
0825     bridge->driver->configure();
0826 
0827     return 0;
0828 }
0829 #endif
0830 
0831 static const struct pci_device_id agp_intel_pci_table[] = {
0832 #define ID(x)                       \
0833     {                       \
0834     .class      = (PCI_CLASS_BRIDGE_HOST << 8), \
0835     .class_mask = ~0,               \
0836     .vendor     = PCI_VENDOR_ID_INTEL,      \
0837     .device     = x,                \
0838     .subvendor  = PCI_ANY_ID,           \
0839     .subdevice  = PCI_ANY_ID,           \
0840     }
0841     ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */
0842     ID(PCI_DEVICE_ID_INTEL_82443LX_0),
0843     ID(PCI_DEVICE_ID_INTEL_82443BX_0),
0844     ID(PCI_DEVICE_ID_INTEL_82443GX_0),
0845     ID(PCI_DEVICE_ID_INTEL_82810_MC1),
0846     ID(PCI_DEVICE_ID_INTEL_82810_MC3),
0847     ID(PCI_DEVICE_ID_INTEL_82810E_MC),
0848     ID(PCI_DEVICE_ID_INTEL_82815_MC),
0849     ID(PCI_DEVICE_ID_INTEL_82820_HB),
0850     ID(PCI_DEVICE_ID_INTEL_82820_UP_HB),
0851     ID(PCI_DEVICE_ID_INTEL_82830_HB),
0852     ID(PCI_DEVICE_ID_INTEL_82840_HB),
0853     ID(PCI_DEVICE_ID_INTEL_82845_HB),
0854     ID(PCI_DEVICE_ID_INTEL_82845G_HB),
0855     ID(PCI_DEVICE_ID_INTEL_82850_HB),
0856     ID(PCI_DEVICE_ID_INTEL_82854_HB),
0857     ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
0858     ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
0859     ID(PCI_DEVICE_ID_INTEL_82860_HB),
0860     ID(PCI_DEVICE_ID_INTEL_82865_HB),
0861     ID(PCI_DEVICE_ID_INTEL_82875_HB),
0862     ID(PCI_DEVICE_ID_INTEL_7505_0),
0863     ID(PCI_DEVICE_ID_INTEL_7205_0),
0864     ID(PCI_DEVICE_ID_INTEL_E7221_HB),
0865     ID(PCI_DEVICE_ID_INTEL_82915G_HB),
0866     ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
0867     ID(PCI_DEVICE_ID_INTEL_82945G_HB),
0868     ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
0869     ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
0870     ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
0871     ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
0872     ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
0873     ID(PCI_DEVICE_ID_INTEL_82G35_HB),
0874     ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
0875     ID(PCI_DEVICE_ID_INTEL_82965G_HB),
0876     ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
0877     ID(PCI_DEVICE_ID_INTEL_82965GME_HB),
0878     ID(PCI_DEVICE_ID_INTEL_G33_HB),
0879     ID(PCI_DEVICE_ID_INTEL_Q35_HB),
0880     ID(PCI_DEVICE_ID_INTEL_Q33_HB),
0881     ID(PCI_DEVICE_ID_INTEL_GM45_HB),
0882     ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
0883     ID(PCI_DEVICE_ID_INTEL_Q45_HB),
0884     ID(PCI_DEVICE_ID_INTEL_G45_HB),
0885     ID(PCI_DEVICE_ID_INTEL_G41_HB),
0886     ID(PCI_DEVICE_ID_INTEL_B43_HB),
0887     ID(PCI_DEVICE_ID_INTEL_B43_1_HB),
0888     ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
0889     ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB),
0890     ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
0891     ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
0892     ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
0893     { }
0894 };
0895 
0896 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
0897 
0898 static struct pci_driver agp_intel_pci_driver = {
0899     .name       = "agpgart-intel",
0900     .id_table   = agp_intel_pci_table,
0901     .probe      = agp_intel_probe,
0902     .remove     = agp_intel_remove,
0903 #ifdef CONFIG_PM
0904     .resume     = agp_intel_resume,
0905 #endif
0906 };
0907 
0908 static int __init agp_intel_init(void)
0909 {
0910     if (agp_off)
0911         return -EINVAL;
0912     return pci_register_driver(&agp_intel_pci_driver);
0913 }
0914 
0915 static void __exit agp_intel_cleanup(void)
0916 {
0917     pci_unregister_driver(&agp_intel_pci_driver);
0918 }
0919 
0920 module_init(agp_intel_init);
0921 module_exit(agp_intel_cleanup);
0922 
0923 MODULE_AUTHOR("Dave Jones, Various @Intel");
0924 MODULE_LICENSE("GPL and additional rights");