linux/drivers/char/agp/intel-agp.c
<<
>>
Prefs
   1/*
   2 * Intel AGPGART routines.
   3 */
   4
   5#include <linux/module.h>
   6#include <linux/pci.h>
   7#include <linux/slab.h>
   8#include <linux/init.h>
   9#include <linux/kernel.h>
  10#include <linux/pagemap.h>
  11#include <linux/agp_backend.h>
  12#include <asm/smp.h>
  13#include "agp.h"
  14#include "intel-agp.h"
  15
  16int intel_agp_enabled;
  17EXPORT_SYMBOL(intel_agp_enabled);
  18
  19static int intel_fetch_size(void)
  20{
  21        int i;
  22        u16 temp;
  23        struct aper_size_info_16 *values;
  24
  25        pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
  26        values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
  27
  28        for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
  29                if (temp == values[i].size_value) {
  30                        agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
  31                        agp_bridge->aperture_size_idx = i;
  32                        return values[i].size;
  33                }
  34        }
  35
  36        return 0;
  37}
  38
  39static int __intel_8xx_fetch_size(u8 temp)
  40{
  41        int i;
  42        struct aper_size_info_8 *values;
  43
  44        values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
  45
  46        for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
  47                if (temp == values[i].size_value) {
  48                        agp_bridge->previous_size =
  49                                agp_bridge->current_size = (void *) (values + i);
  50                        agp_bridge->aperture_size_idx = i;
  51                        return values[i].size;
  52                }
  53        }
  54        return 0;
  55}
  56
  57static int intel_8xx_fetch_size(void)
  58{
  59        u8 temp;
  60
  61        pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
  62        return __intel_8xx_fetch_size(temp);
  63}
  64
  65static int intel_815_fetch_size(void)
  66{
  67        u8 temp;
  68
  69        /* Intel 815 chipsets have a _weird_ APSIZE register with only
  70         * one non-reserved bit, so mask the others out ... */
  71        pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
  72        temp &= (1 << 3);
  73
  74        return __intel_8xx_fetch_size(temp);
  75}
  76
  77static void intel_tlbflush(struct agp_memory *mem)
  78{
  79        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
  80        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
  81}
  82
  83
  84static void intel_8xx_tlbflush(struct agp_memory *mem)
  85{
  86        u32 temp;
  87        pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
  88        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
  89        pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
  90        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
  91}
  92
  93
  94static void intel_cleanup(void)
  95{
  96        u16 temp;
  97        struct aper_size_info_16 *previous_size;
  98
  99        previous_size = A_SIZE_16(agp_bridge->previous_size);
 100        pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
 101        pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
 102        pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
 103}
 104
 105
 106static void intel_8xx_cleanup(void)
 107{
 108        u16 temp;
 109        struct aper_size_info_8 *previous_size;
 110
 111        previous_size = A_SIZE_8(agp_bridge->previous_size);
 112        pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
 113        pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
 114        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
 115}
 116
 117
 118static int intel_configure(void)
 119{
 120        u32 temp;
 121        u16 temp2;
 122        struct aper_size_info_16 *current_size;
 123
 124        current_size = A_SIZE_16(agp_bridge->current_size);
 125
 126        /* aperture size */
 127        pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 128
 129        /* address to map to */
 130        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 131        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 132
 133        /* attbase - aperture base */
 134        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 135
 136        /* agpctrl */
 137        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
 138
 139        /* paccfg/nbxcfg */
 140        pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
 141        pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
 142                        (temp2 & ~(1 << 10)) | (1 << 9));
 143        /* clear any possible error conditions */
 144        pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
 145        return 0;
 146}
 147
 148static int intel_815_configure(void)
 149{
 150        u32 temp, addr;
 151        u8 temp2;
 152        struct aper_size_info_8 *current_size;
 153
 154        /* attbase - aperture base */
 155        /* the Intel 815 chipset spec. says that bits 29-31 in the
 156        * ATTBASE register are reserved -> try not to write them */
 157        if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
 158                dev_emerg(&agp_bridge->dev->dev, "gatt bus addr too high");
 159                return -EINVAL;
 160        }
 161
 162        current_size = A_SIZE_8(agp_bridge->current_size);
 163
 164        /* aperture size */
 165        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
 166                        current_size->size_value);
 167
 168        /* address to map to */
 169        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 170        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 171
 172        pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);
 173        addr &= INTEL_815_ATTBASE_MASK;
 174        addr |= agp_bridge->gatt_bus_addr;
 175        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);
 176
 177        /* agpctrl */
 178        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 179
 180        /* apcont */
 181        pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);
 182        pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));
 183
 184        /* clear any possible error conditions */
 185        /* Oddness : this chipset seems to have no ERRSTS register ! */
 186        return 0;
 187}
 188
 189static void intel_820_tlbflush(struct agp_memory *mem)
 190{
 191        return;
 192}
 193
 194static void intel_820_cleanup(void)
 195{
 196        u8 temp;
 197        struct aper_size_info_8 *previous_size;
 198
 199        previous_size = A_SIZE_8(agp_bridge->previous_size);
 200        pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);
 201        pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR,
 202                        temp & ~(1 << 1));
 203        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
 204                        previous_size->size_value);
 205}
 206
 207
 208static int intel_820_configure(void)
 209{
 210        u32 temp;
 211        u8 temp2;
 212        struct aper_size_info_8 *current_size;
 213
 214        current_size = A_SIZE_8(agp_bridge->current_size);
 215
 216        /* aperture size */
 217        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 218
 219        /* address to map to */
 220        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 221        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 222
 223        /* attbase - aperture base */
 224        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 225
 226        /* agpctrl */
 227        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 228
 229        /* global enable aperture access */
 230        /* This flag is not accessed through MCHCFG register as in */
 231        /* i850 chipset. */
 232        pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);
 233        pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));
 234        /* clear any possible AGP-related error conditions */
 235        pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c);
 236        return 0;
 237}
 238
 239static int intel_840_configure(void)
 240{
 241        u32 temp;
 242        u16 temp2;
 243        struct aper_size_info_8 *current_size;
 244
 245        current_size = A_SIZE_8(agp_bridge->current_size);
 246
 247        /* aperture size */
 248        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 249
 250        /* address to map to */
 251        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 252        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 253
 254        /* attbase - aperture base */
 255        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 256
 257        /* agpctrl */
 258        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 259
 260        /* mcgcfg */
 261        pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);
 262        pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
 263        /* clear any possible error conditions */
 264        pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000);
 265        return 0;
 266}
 267
 268static int intel_845_configure(void)
 269{
 270        u32 temp;
 271        u8 temp2;
 272        struct aper_size_info_8 *current_size;
 273
 274        current_size = A_SIZE_8(agp_bridge->current_size);
 275
 276        /* aperture size */
 277        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 278
 279        if (agp_bridge->apbase_config != 0) {
 280                pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
 281                                       agp_bridge->apbase_config);
 282        } else {
 283                /* address to map to */
 284                pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 285                agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 286                agp_bridge->apbase_config = temp;
 287        }
 288
 289        /* attbase - aperture base */
 290        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 291
 292        /* agpctrl */
 293        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 294
 295        /* agpm */
 296        pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
 297        pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
 298        /* clear any possible error conditions */
 299        pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
 300        return 0;
 301}
 302
 303static int intel_850_configure(void)
 304{
 305        u32 temp;
 306        u16 temp2;
 307        struct aper_size_info_8 *current_size;
 308
 309        current_size = A_SIZE_8(agp_bridge->current_size);
 310
 311        /* aperture size */
 312        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 313
 314        /* address to map to */
 315        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 316        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 317
 318        /* attbase - aperture base */
 319        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 320
 321        /* agpctrl */
 322        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 323
 324        /* mcgcfg */
 325        pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);
 326        pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
 327        /* clear any possible AGP-related error conditions */
 328        pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c);
 329        return 0;
 330}
 331
 332static int intel_860_configure(void)
 333{
 334        u32 temp;
 335        u16 temp2;
 336        struct aper_size_info_8 *current_size;
 337
 338        current_size = A_SIZE_8(agp_bridge->current_size);
 339
 340        /* aperture size */
 341        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 342
 343        /* address to map to */
 344        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 345        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 346
 347        /* attbase - aperture base */
 348        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 349
 350        /* agpctrl */
 351        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 352
 353        /* mcgcfg */
 354        pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);
 355        pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
 356        /* clear any possible AGP-related error conditions */
 357        pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);
 358        return 0;
 359}
 360
 361static int intel_830mp_configure(void)
 362{
 363        u32 temp;
 364        u16 temp2;
 365        struct aper_size_info_8 *current_size;
 366
 367        current_size = A_SIZE_8(agp_bridge->current_size);
 368
 369        /* aperture size */
 370        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 371
 372        /* address to map to */
 373        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 374        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 375
 376        /* attbase - aperture base */
 377        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 378
 379        /* agpctrl */
 380        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 381
 382        /* gmch */
 383        pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
 384        pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));
 385        /* clear any possible AGP-related error conditions */
 386        pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);
 387        return 0;
 388}
 389
 390static int intel_7505_configure(void)
 391{
 392        u32 temp;
 393        u16 temp2;
 394        struct aper_size_info_8 *current_size;
 395
 396        current_size = A_SIZE_8(agp_bridge->current_size);
 397
 398        /* aperture size */
 399        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 400
 401        /* address to map to */
 402        pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
 403        agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 404
 405        /* attbase - aperture base */
 406        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 407
 408        /* agpctrl */
 409        pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 410
 411        /* mchcfg */
 412        pci_read_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, &temp2);
 413        pci_write_config_word(agp_bridge->dev, INTEL_I7505_MCHCFG, temp2 | (1 << 9));
 414
 415        return 0;
 416}
 417
 418/* Setup function */
 419static const struct gatt_mask intel_generic_masks[] =
 420{
 421        {.mask = 0x00000017, .type = 0}
 422};
 423
 424static const struct aper_size_info_8 intel_815_sizes[2] =
 425{
 426        {64, 16384, 4, 0},
 427        {32, 8192, 3, 8},
 428};
 429
 430static const struct aper_size_info_8 intel_8xx_sizes[7] =
 431{
 432        {256, 65536, 6, 0},
 433        {128, 32768, 5, 32},
 434        {64, 16384, 4, 48},
 435        {32, 8192, 3, 56},
 436        {16, 4096, 2, 60},
 437        {8, 2048, 1, 62},
 438        {4, 1024, 0, 63}
 439};
 440
 441static const struct aper_size_info_16 intel_generic_sizes[7] =
 442{
 443        {256, 65536, 6, 0},
 444        {128, 32768, 5, 32},
 445        {64, 16384, 4, 48},
 446        {32, 8192, 3, 56},
 447        {16, 4096, 2, 60},
 448        {8, 2048, 1, 62},
 449        {4, 1024, 0, 63}
 450};
 451
 452static const struct aper_size_info_8 intel_830mp_sizes[4] =
 453{
 454        {256, 65536, 6, 0},
 455        {128, 32768, 5, 32},
 456        {64, 16384, 4, 48},
 457        {32, 8192, 3, 56}
 458};
 459
 460static const struct agp_bridge_driver intel_generic_driver = {
 461        .owner                  = THIS_MODULE,
 462        .aperture_sizes         = intel_generic_sizes,
 463        .size_type              = U16_APER_SIZE,
 464        .num_aperture_sizes     = 7,
 465        .needs_scratch_page     = true,
 466        .configure              = intel_configure,
 467        .fetch_size             = intel_fetch_size,
 468        .cleanup                = intel_cleanup,
 469        .tlb_flush              = intel_tlbflush,
 470        .mask_memory            = agp_generic_mask_memory,
 471        .masks                  = intel_generic_masks,
 472        .agp_enable             = agp_generic_enable,
 473        .cache_flush            = global_cache_flush,
 474        .create_gatt_table      = agp_generic_create_gatt_table,
 475        .free_gatt_table        = agp_generic_free_gatt_table,
 476        .insert_memory          = agp_generic_insert_memory,
 477        .remove_memory          = agp_generic_remove_memory,
 478        .alloc_by_type          = agp_generic_alloc_by_type,
 479        .free_by_type           = agp_generic_free_by_type,
 480        .agp_alloc_page         = agp_generic_alloc_page,
 481        .agp_alloc_pages        = agp_generic_alloc_pages,
 482        .agp_destroy_page       = agp_generic_destroy_page,
 483        .agp_destroy_pages      = agp_generic_destroy_pages,
 484        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 485};
 486
 487static const struct agp_bridge_driver intel_815_driver = {
 488        .owner                  = THIS_MODULE,
 489        .aperture_sizes         = intel_815_sizes,
 490        .size_type              = U8_APER_SIZE,
 491        .num_aperture_sizes     = 2,
 492        .needs_scratch_page     = true,
 493        .configure              = intel_815_configure,
 494        .fetch_size             = intel_815_fetch_size,
 495        .cleanup                = intel_8xx_cleanup,
 496        .tlb_flush              = intel_8xx_tlbflush,
 497        .mask_memory            = agp_generic_mask_memory,
 498        .masks                  = intel_generic_masks,
 499        .agp_enable             = agp_generic_enable,
 500        .cache_flush            = global_cache_flush,
 501        .create_gatt_table      = agp_generic_create_gatt_table,
 502        .free_gatt_table        = agp_generic_free_gatt_table,
 503        .insert_memory          = agp_generic_insert_memory,
 504        .remove_memory          = agp_generic_remove_memory,
 505        .alloc_by_type          = agp_generic_alloc_by_type,
 506        .free_by_type           = agp_generic_free_by_type,
 507        .agp_alloc_page         = agp_generic_alloc_page,
 508        .agp_alloc_pages        = agp_generic_alloc_pages,
 509        .agp_destroy_page       = agp_generic_destroy_page,
 510        .agp_destroy_pages      = agp_generic_destroy_pages,
 511        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 512};
 513
 514static const struct agp_bridge_driver intel_820_driver = {
 515        .owner                  = THIS_MODULE,
 516        .aperture_sizes         = intel_8xx_sizes,
 517        .size_type              = U8_APER_SIZE,
 518        .num_aperture_sizes     = 7,
 519        .needs_scratch_page     = true,
 520        .configure              = intel_820_configure,
 521        .fetch_size             = intel_8xx_fetch_size,
 522        .cleanup                = intel_820_cleanup,
 523        .tlb_flush              = intel_820_tlbflush,
 524        .mask_memory            = agp_generic_mask_memory,
 525        .masks                  = intel_generic_masks,
 526        .agp_enable             = agp_generic_enable,
 527        .cache_flush            = global_cache_flush,
 528        .create_gatt_table      = agp_generic_create_gatt_table,
 529        .free_gatt_table        = agp_generic_free_gatt_table,
 530        .insert_memory          = agp_generic_insert_memory,
 531        .remove_memory          = agp_generic_remove_memory,
 532        .alloc_by_type          = agp_generic_alloc_by_type,
 533        .free_by_type           = agp_generic_free_by_type,
 534        .agp_alloc_page         = agp_generic_alloc_page,
 535        .agp_alloc_pages        = agp_generic_alloc_pages,
 536        .agp_destroy_page       = agp_generic_destroy_page,
 537        .agp_destroy_pages      = agp_generic_destroy_pages,
 538        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 539};
 540
 541static const struct agp_bridge_driver intel_830mp_driver = {
 542        .owner                  = THIS_MODULE,
 543        .aperture_sizes         = intel_830mp_sizes,
 544        .size_type              = U8_APER_SIZE,
 545        .num_aperture_sizes     = 4,
 546        .needs_scratch_page     = true,
 547        .configure              = intel_830mp_configure,
 548        .fetch_size             = intel_8xx_fetch_size,
 549        .cleanup                = intel_8xx_cleanup,
 550        .tlb_flush              = intel_8xx_tlbflush,
 551        .mask_memory            = agp_generic_mask_memory,
 552        .masks                  = intel_generic_masks,
 553        .agp_enable             = agp_generic_enable,
 554        .cache_flush            = global_cache_flush,
 555        .create_gatt_table      = agp_generic_create_gatt_table,
 556        .free_gatt_table        = agp_generic_free_gatt_table,
 557        .insert_memory          = agp_generic_insert_memory,
 558        .remove_memory          = agp_generic_remove_memory,
 559        .alloc_by_type          = agp_generic_alloc_by_type,
 560        .free_by_type           = agp_generic_free_by_type,
 561        .agp_alloc_page         = agp_generic_alloc_page,
 562        .agp_alloc_pages        = agp_generic_alloc_pages,
 563        .agp_destroy_page       = agp_generic_destroy_page,
 564        .agp_destroy_pages      = agp_generic_destroy_pages,
 565        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 566};
 567
 568static const struct agp_bridge_driver intel_840_driver = {
 569        .owner                  = THIS_MODULE,
 570        .aperture_sizes         = intel_8xx_sizes,
 571        .size_type              = U8_APER_SIZE,
 572        .num_aperture_sizes     = 7,
 573        .needs_scratch_page     = true,
 574        .configure              = intel_840_configure,
 575        .fetch_size             = intel_8xx_fetch_size,
 576        .cleanup                = intel_8xx_cleanup,
 577        .tlb_flush              = intel_8xx_tlbflush,
 578        .mask_memory            = agp_generic_mask_memory,
 579        .masks                  = intel_generic_masks,
 580        .agp_enable             = agp_generic_enable,
 581        .cache_flush            = global_cache_flush,
 582        .create_gatt_table      = agp_generic_create_gatt_table,
 583        .free_gatt_table        = agp_generic_free_gatt_table,
 584        .insert_memory          = agp_generic_insert_memory,
 585        .remove_memory          = agp_generic_remove_memory,
 586        .alloc_by_type          = agp_generic_alloc_by_type,
 587        .free_by_type           = agp_generic_free_by_type,
 588        .agp_alloc_page         = agp_generic_alloc_page,
 589        .agp_alloc_pages        = agp_generic_alloc_pages,
 590        .agp_destroy_page       = agp_generic_destroy_page,
 591        .agp_destroy_pages      = agp_generic_destroy_pages,
 592        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 593};
 594
 595static const struct agp_bridge_driver intel_845_driver = {
 596        .owner                  = THIS_MODULE,
 597        .aperture_sizes         = intel_8xx_sizes,
 598        .size_type              = U8_APER_SIZE,
 599        .num_aperture_sizes     = 7,
 600        .needs_scratch_page     = true,
 601        .configure              = intel_845_configure,
 602        .fetch_size             = intel_8xx_fetch_size,
 603        .cleanup                = intel_8xx_cleanup,
 604        .tlb_flush              = intel_8xx_tlbflush,
 605        .mask_memory            = agp_generic_mask_memory,
 606        .masks                  = intel_generic_masks,
 607        .agp_enable             = agp_generic_enable,
 608        .cache_flush            = global_cache_flush,
 609        .create_gatt_table      = agp_generic_create_gatt_table,
 610        .free_gatt_table        = agp_generic_free_gatt_table,
 611        .insert_memory          = agp_generic_insert_memory,
 612        .remove_memory          = agp_generic_remove_memory,
 613        .alloc_by_type          = agp_generic_alloc_by_type,
 614        .free_by_type           = agp_generic_free_by_type,
 615        .agp_alloc_page         = agp_generic_alloc_page,
 616        .agp_alloc_pages        = agp_generic_alloc_pages,
 617        .agp_destroy_page       = agp_generic_destroy_page,
 618        .agp_destroy_pages      = agp_generic_destroy_pages,
 619        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 620};
 621
 622static const struct agp_bridge_driver intel_850_driver = {
 623        .owner                  = THIS_MODULE,
 624        .aperture_sizes         = intel_8xx_sizes,
 625        .size_type              = U8_APER_SIZE,
 626        .num_aperture_sizes     = 7,
 627        .needs_scratch_page     = true,
 628        .configure              = intel_850_configure,
 629        .fetch_size             = intel_8xx_fetch_size,
 630        .cleanup                = intel_8xx_cleanup,
 631        .tlb_flush              = intel_8xx_tlbflush,
 632        .mask_memory            = agp_generic_mask_memory,
 633        .masks                  = intel_generic_masks,
 634        .agp_enable             = agp_generic_enable,
 635        .cache_flush            = global_cache_flush,
 636        .create_gatt_table      = agp_generic_create_gatt_table,
 637        .free_gatt_table        = agp_generic_free_gatt_table,
 638        .insert_memory          = agp_generic_insert_memory,
 639        .remove_memory          = agp_generic_remove_memory,
 640        .alloc_by_type          = agp_generic_alloc_by_type,
 641        .free_by_type           = agp_generic_free_by_type,
 642        .agp_alloc_page         = agp_generic_alloc_page,
 643        .agp_alloc_pages        = agp_generic_alloc_pages,
 644        .agp_destroy_page       = agp_generic_destroy_page,
 645        .agp_destroy_pages      = agp_generic_destroy_pages,
 646        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 647};
 648
 649static const struct agp_bridge_driver intel_860_driver = {
 650        .owner                  = THIS_MODULE,
 651        .aperture_sizes         = intel_8xx_sizes,
 652        .size_type              = U8_APER_SIZE,
 653        .num_aperture_sizes     = 7,
 654        .needs_scratch_page     = true,
 655        .configure              = intel_860_configure,
 656        .fetch_size             = intel_8xx_fetch_size,
 657        .cleanup                = intel_8xx_cleanup,
 658        .tlb_flush              = intel_8xx_tlbflush,
 659        .mask_memory            = agp_generic_mask_memory,
 660        .masks                  = intel_generic_masks,
 661        .agp_enable             = agp_generic_enable,
 662        .cache_flush            = global_cache_flush,
 663        .create_gatt_table      = agp_generic_create_gatt_table,
 664        .free_gatt_table        = agp_generic_free_gatt_table,
 665        .insert_memory          = agp_generic_insert_memory,
 666        .remove_memory          = agp_generic_remove_memory,
 667        .alloc_by_type          = agp_generic_alloc_by_type,
 668        .free_by_type           = agp_generic_free_by_type,
 669        .agp_alloc_page         = agp_generic_alloc_page,
 670        .agp_alloc_pages        = agp_generic_alloc_pages,
 671        .agp_destroy_page       = agp_generic_destroy_page,
 672        .agp_destroy_pages      = agp_generic_destroy_pages,
 673        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 674};
 675
 676static const struct agp_bridge_driver intel_7505_driver = {
 677        .owner                  = THIS_MODULE,
 678        .aperture_sizes         = intel_8xx_sizes,
 679        .size_type              = U8_APER_SIZE,
 680        .num_aperture_sizes     = 7,
 681        .needs_scratch_page     = true,
 682        .configure              = intel_7505_configure,
 683        .fetch_size             = intel_8xx_fetch_size,
 684        .cleanup                = intel_8xx_cleanup,
 685        .tlb_flush              = intel_8xx_tlbflush,
 686        .mask_memory            = agp_generic_mask_memory,
 687        .masks                  = intel_generic_masks,
 688        .agp_enable             = agp_generic_enable,
 689        .cache_flush            = global_cache_flush,
 690        .create_gatt_table      = agp_generic_create_gatt_table,
 691        .free_gatt_table        = agp_generic_free_gatt_table,
 692        .insert_memory          = agp_generic_insert_memory,
 693        .remove_memory          = agp_generic_remove_memory,
 694        .alloc_by_type          = agp_generic_alloc_by_type,
 695        .free_by_type           = agp_generic_free_by_type,
 696        .agp_alloc_page         = agp_generic_alloc_page,
 697        .agp_alloc_pages        = agp_generic_alloc_pages,
 698        .agp_destroy_page       = agp_generic_destroy_page,
 699        .agp_destroy_pages      = agp_generic_destroy_pages,
 700        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 701};
 702
 703/* Table to describe Intel GMCH and AGP/PCIE GART drivers.  At least one of
 704 * driver and gmch_driver must be non-null, and find_gmch will determine
 705 * which one should be used if a gmch_chip_id is present.
 706 */
 707static const struct intel_agp_driver_description {
 708        unsigned int chip_id;
 709        char *name;
 710        const struct agp_bridge_driver *driver;
 711} intel_agp_chipsets[] = {
 712        { PCI_DEVICE_ID_INTEL_82443LX_0, "440LX", &intel_generic_driver },
 713        { PCI_DEVICE_ID_INTEL_82443BX_0, "440BX", &intel_generic_driver },
 714        { PCI_DEVICE_ID_INTEL_82443GX_0, "440GX", &intel_generic_driver },
 715        { PCI_DEVICE_ID_INTEL_82815_MC, "i815", &intel_815_driver },
 716        { PCI_DEVICE_ID_INTEL_82820_HB, "i820", &intel_820_driver },
 717        { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver },
 718        { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver },
 719        { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver },
 720        { PCI_DEVICE_ID_INTEL_82845_HB, "i845", &intel_845_driver },
 721        { PCI_DEVICE_ID_INTEL_82845G_HB, "845G", &intel_845_driver },
 722        { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver },
 723        { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver },
 724        { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver },
 725        { PCI_DEVICE_ID_INTEL_82855GM_HB, "855GM", &intel_845_driver },
 726        { PCI_DEVICE_ID_INTEL_82860_HB, "i860", &intel_860_driver },
 727        { PCI_DEVICE_ID_INTEL_82865_HB, "865", &intel_845_driver },
 728        { PCI_DEVICE_ID_INTEL_82875_HB, "i875", &intel_845_driver },
 729        { PCI_DEVICE_ID_INTEL_7505_0, "E7505", &intel_7505_driver },
 730        { PCI_DEVICE_ID_INTEL_7205_0, "E7205", &intel_7505_driver },
 731        { 0, NULL, NULL }
 732};
 733
 734static int __devinit agp_intel_probe(struct pci_dev *pdev,
 735                                     const struct pci_device_id *ent)
 736{
 737        struct agp_bridge_data *bridge;
 738        u8 cap_ptr = 0;
 739        struct resource *r;
 740        int i, err;
 741
 742        cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 743
 744        bridge = agp_alloc_bridge();
 745        if (!bridge)
 746                return -ENOMEM;
 747
 748        bridge->capndx = cap_ptr;
 749
 750        if (intel_gmch_probe(pdev, bridge))
 751                goto found_gmch;
 752
 753        for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
 754                /* In case that multiple models of gfx chip may
 755                   stand on same host bridge type, this can be
 756                   sure we detect the right IGD. */
 757                if (pdev->device == intel_agp_chipsets[i].chip_id) {
 758                        bridge->driver = intel_agp_chipsets[i].driver;
 759                        break;
 760                }
 761        }
 762
 763        if (!bridge->driver) {
 764                if (cap_ptr)
 765                        dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n",
 766                                 pdev->vendor, pdev->device);
 767                agp_put_bridge(bridge);
 768                return -ENODEV;
 769        }
 770
 771        bridge->dev = pdev;
 772        bridge->dev_private_data = NULL;
 773
 774        dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
 775
 776        /*
 777        * The following fixes the case where the BIOS has "forgotten" to
 778        * provide an address range for the GART.
 779        * 20030610 - hamish@zot.org
 780        * This happens before pci_enable_device() intentionally;
 781        * calling pci_enable_device() before assigning the resource
 782        * will result in the GART being disabled on machines with such
 783        * BIOSs (the GART ends up with a BAR starting at 0, which
 784        * conflicts a lot of other devices).
 785        */
 786        r = &pdev->resource[0];
 787        if (!r->start && r->end) {
 788                if (pci_assign_resource(pdev, 0)) {
 789                        dev_err(&pdev->dev, "can't assign resource 0\n");
 790                        agp_put_bridge(bridge);
 791                        return -ENODEV;
 792                }
 793        }
 794
 795        /*
 796        * If the device has not been properly setup, the following will catch
 797        * the problem and should stop the system from crashing.
 798        * 20030610 - hamish@zot.org
 799        */
 800        if (pci_enable_device(pdev)) {
 801                dev_err(&pdev->dev, "can't enable PCI device\n");
 802                agp_put_bridge(bridge);
 803                return -ENODEV;
 804        }
 805
 806        /* Fill in the mode register */
 807        if (cap_ptr) {
 808                pci_read_config_dword(pdev,
 809                                bridge->capndx+PCI_AGP_STATUS,
 810                                &bridge->mode);
 811        }
 812
 813found_gmch:
 814        pci_set_drvdata(pdev, bridge);
 815        err = agp_add_bridge(bridge);
 816        if (!err)
 817                intel_agp_enabled = 1;
 818        return err;
 819}
 820
 821static void __devexit agp_intel_remove(struct pci_dev *pdev)
 822{
 823        struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 824
 825        agp_remove_bridge(bridge);
 826
 827        intel_gmch_remove(pdev);
 828
 829        agp_put_bridge(bridge);
 830}
 831
 832#ifdef CONFIG_PM
 833static int agp_intel_resume(struct pci_dev *pdev)
 834{
 835        struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 836
 837        bridge->driver->configure();
 838
 839        return 0;
 840}
 841#endif
 842
 843static struct pci_device_id agp_intel_pci_table[] = {
 844#define ID(x)                                           \
 845        {                                               \
 846        .class          = (PCI_CLASS_BRIDGE_HOST << 8), \
 847        .class_mask     = ~0,                           \
 848        .vendor         = PCI_VENDOR_ID_INTEL,          \
 849        .device         = x,                            \
 850        .subvendor      = PCI_ANY_ID,                   \
 851        .subdevice      = PCI_ANY_ID,                   \
 852        }
 853        ID(PCI_DEVICE_ID_INTEL_82443LX_0),
 854        ID(PCI_DEVICE_ID_INTEL_82443BX_0),
 855        ID(PCI_DEVICE_ID_INTEL_82443GX_0),
 856        ID(PCI_DEVICE_ID_INTEL_82810_MC1),
 857        ID(PCI_DEVICE_ID_INTEL_82810_MC3),
 858        ID(PCI_DEVICE_ID_INTEL_82810E_MC),
 859        ID(PCI_DEVICE_ID_INTEL_82815_MC),
 860        ID(PCI_DEVICE_ID_INTEL_82820_HB),
 861        ID(PCI_DEVICE_ID_INTEL_82820_UP_HB),
 862        ID(PCI_DEVICE_ID_INTEL_82830_HB),
 863        ID(PCI_DEVICE_ID_INTEL_82840_HB),
 864        ID(PCI_DEVICE_ID_INTEL_82845_HB),
 865        ID(PCI_DEVICE_ID_INTEL_82845G_HB),
 866        ID(PCI_DEVICE_ID_INTEL_82850_HB),
 867        ID(PCI_DEVICE_ID_INTEL_82854_HB),
 868        ID(PCI_DEVICE_ID_INTEL_82855PM_HB),
 869        ID(PCI_DEVICE_ID_INTEL_82855GM_HB),
 870        ID(PCI_DEVICE_ID_INTEL_82860_HB),
 871        ID(PCI_DEVICE_ID_INTEL_82865_HB),
 872        ID(PCI_DEVICE_ID_INTEL_82875_HB),
 873        ID(PCI_DEVICE_ID_INTEL_7505_0),
 874        ID(PCI_DEVICE_ID_INTEL_7205_0),
 875        ID(PCI_DEVICE_ID_INTEL_E7221_HB),
 876        ID(PCI_DEVICE_ID_INTEL_82915G_HB),
 877        ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
 878        ID(PCI_DEVICE_ID_INTEL_82945G_HB),
 879        ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
 880        ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
 881        ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB),
 882        ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB),
 883        ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
 884        ID(PCI_DEVICE_ID_INTEL_82G35_HB),
 885        ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
 886        ID(PCI_DEVICE_ID_INTEL_82965G_HB),
 887        ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
 888        ID(PCI_DEVICE_ID_INTEL_82965GME_HB),
 889        ID(PCI_DEVICE_ID_INTEL_G33_HB),
 890        ID(PCI_DEVICE_ID_INTEL_Q35_HB),
 891        ID(PCI_DEVICE_ID_INTEL_Q33_HB),
 892        ID(PCI_DEVICE_ID_INTEL_GM45_HB),
 893        ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB),
 894        ID(PCI_DEVICE_ID_INTEL_Q45_HB),
 895        ID(PCI_DEVICE_ID_INTEL_G45_HB),
 896        ID(PCI_DEVICE_ID_INTEL_G41_HB),
 897        ID(PCI_DEVICE_ID_INTEL_B43_HB),
 898        ID(PCI_DEVICE_ID_INTEL_B43_1_HB),
 899        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB),
 900        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
 901        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
 902        ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
 903        ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
 904        ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
 905        ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
 906        ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB),
 907        ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB),
 908        ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB),
 909        { }
 910};
 911
 912MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
 913
 914static struct pci_driver agp_intel_pci_driver = {
 915        .name           = "agpgart-intel",
 916        .id_table       = agp_intel_pci_table,
 917        .probe          = agp_intel_probe,
 918        .remove         = __devexit_p(agp_intel_remove),
 919#ifdef CONFIG_PM
 920        .resume         = agp_intel_resume,
 921#endif
 922};
 923
 924static int __init agp_intel_init(void)
 925{
 926        if (agp_off)
 927                return -EINVAL;
 928        return pci_register_driver(&agp_intel_pci_driver);
 929}
 930
 931static void __exit agp_intel_cleanup(void)
 932{
 933        pci_unregister_driver(&agp_intel_pci_driver);
 934}
 935
 936module_init(agp_intel_init);
 937module_exit(agp_intel_cleanup);
 938
 939MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
 940MODULE_LICENSE("GPL and additional rights");
 941
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.