linux/drivers/char/agp/uninorth-agp.c
<<
>>
Prefs
   1/*
   2 * UniNorth AGPGART routines.
   3 */
   4#include <linux/module.h>
   5#include <linux/pci.h>
   6#include <linux/init.h>
   7#include <linux/pagemap.h>
   8#include <linux/agp_backend.h>
   9#include <linux/delay.h>
  10#include <linux/vmalloc.h>
  11#include <asm/uninorth.h>
  12#include <asm/pci-bridge.h>
  13#include <asm/prom.h>
  14#include <asm/pmac_feature.h>
  15#include "agp.h"
  16
  17/*
  18 * NOTES for uninorth3 (G5 AGP) supports :
  19 *
  20 * There maybe also possibility to have bigger cache line size for
  21 * agp (see pmac_pci.c and look for cache line). Need to be investigated
  22 * by someone.
  23 *
  24 * PAGE size are hardcoded but this may change, see asm/page.h.
  25 *
  26 * Jerome Glisse <j.glisse@gmail.com>
  27 */
  28static int uninorth_rev;
  29static int is_u3;
  30
  31#define DEFAULT_APERTURE_SIZE 256
  32#define DEFAULT_APERTURE_STRING "256"
  33static char *aperture = NULL;
  34
  35static int uninorth_fetch_size(void)
  36{
  37        int i, size = 0;
  38        struct aper_size_info_32 *values =
  39            A_SIZE_32(agp_bridge->driver->aperture_sizes);
  40
  41        if (aperture) {
  42                char *save = aperture;
  43
  44                size = memparse(aperture, &aperture) >> 20;
  45                aperture = save;
  46
  47                for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
  48                        if (size == values[i].size)
  49                                break;
  50
  51                if (i == agp_bridge->driver->num_aperture_sizes) {
  52                        dev_err(&agp_bridge->dev->dev, "invalid aperture size, "
  53                                "using default\n");
  54                        size = 0;
  55                        aperture = NULL;
  56                }
  57        }
  58
  59        if (!size) {
  60                for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
  61                        if (values[i].size == DEFAULT_APERTURE_SIZE)
  62                                break;
  63        }
  64
  65        agp_bridge->previous_size =
  66            agp_bridge->current_size = (void *)(values + i);
  67        agp_bridge->aperture_size_idx = i;
  68        return values[i].size;
  69}
  70
  71static void uninorth_tlbflush(struct agp_memory *mem)
  72{
  73        u32 ctrl = UNI_N_CFG_GART_ENABLE;
  74
  75        if (is_u3)
  76                ctrl |= U3_N_CFG_GART_PERFRD;
  77        pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  78                               ctrl | UNI_N_CFG_GART_INVAL);
  79        pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, ctrl);
  80
  81        if (uninorth_rev <= 0x30) {
  82                pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  83                                       ctrl | UNI_N_CFG_GART_2xRESET);
  84                pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
  85                                       ctrl);
  86        }
  87}
  88
  89static void uninorth_cleanup(void)
  90{
  91        u32 tmp;
  92
  93        pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, &tmp);
  94        if (!(tmp & UNI_N_CFG_GART_ENABLE))
  95                return;
  96        tmp |= UNI_N_CFG_GART_INVAL;
  97        pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, tmp);
  98        pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, 0);
  99
 100        if (uninorth_rev <= 0x30) {
 101                pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
 102                                       UNI_N_CFG_GART_2xRESET);
 103                pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
 104                                       0);
 105        }
 106}
 107
 108static int uninorth_configure(void)
 109{
 110        struct aper_size_info_32 *current_size;
 111
 112        current_size = A_SIZE_32(agp_bridge->current_size);
 113
 114        dev_info(&agp_bridge->dev->dev, "configuring for size idx: %d\n",
 115                 current_size->size_value);
 116
 117        /* aperture size and gatt addr */
 118        pci_write_config_dword(agp_bridge->dev,
 119                UNI_N_CFG_GART_BASE,
 120                (agp_bridge->gatt_bus_addr & 0xfffff000)
 121                        | current_size->size_value);
 122
 123        /* HACK ALERT
 124         * UniNorth seem to be buggy enough not to handle properly when
 125         * the AGP aperture isn't mapped at bus physical address 0
 126         */
 127        agp_bridge->gart_bus_addr = 0;
 128#ifdef CONFIG_PPC64
 129        /* Assume U3 or later on PPC64 systems */
 130        /* high 4 bits of GART physical address go in UNI_N_CFG_AGP_BASE */
 131        pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_AGP_BASE,
 132                               (agp_bridge->gatt_bus_addr >> 32) & 0xf);
 133#else
 134        pci_write_config_dword(agp_bridge->dev,
 135                UNI_N_CFG_AGP_BASE, agp_bridge->gart_bus_addr);
 136#endif
 137
 138        if (is_u3) {
 139                pci_write_config_dword(agp_bridge->dev,
 140                                       UNI_N_CFG_GART_DUMMY_PAGE,
 141                                       page_to_phys(agp_bridge->scratch_page_page) >> 12);
 142        }
 143
 144        return 0;
 145}
 146
 147static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start,
 148                                int type)
 149{
 150        int i, j, num_entries;
 151        void *temp;
 152        int mask_type;
 153
 154        temp = agp_bridge->current_size;
 155        num_entries = A_SIZE_32(temp)->num_entries;
 156
 157        if (type != mem->type)
 158                return -EINVAL;
 159
 160        mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
 161        if (mask_type != 0) {
 162                /* We know nothing of memory types */
 163                return -EINVAL;
 164        }
 165
 166        if ((pg_start + mem->page_count) > num_entries)
 167                return -EINVAL;
 168
 169        j = pg_start;
 170
 171        while (j < (pg_start + mem->page_count)) {
 172                if (agp_bridge->gatt_table[j])
 173                        return -EBUSY;
 174                j++;
 175        }
 176
 177        for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 178                agp_bridge->gatt_table[j] =
 179                        cpu_to_le32((page_to_phys(mem->pages[i]) & 0xFFFFF000UL) | 0x1UL);
 180                flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])),
 181                                   (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000);
 182        }
 183        (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
 184        mb();
 185
 186        uninorth_tlbflush(mem);
 187        return 0;
 188}
 189
 190static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 191{
 192        int i, num_entries;
 193        void *temp;
 194        u32 *gp;
 195        int mask_type;
 196
 197        temp = agp_bridge->current_size;
 198        num_entries = A_SIZE_32(temp)->num_entries;
 199
 200        if (type != mem->type)
 201                return -EINVAL;
 202
 203        mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type);
 204        if (mask_type != 0) {
 205                /* We know nothing of memory types */
 206                return -EINVAL;
 207        }
 208
 209        if ((pg_start + mem->page_count) > num_entries)
 210                return -EINVAL;
 211
 212        gp = (u32 *) &agp_bridge->gatt_table[pg_start];
 213        for (i = 0; i < mem->page_count; ++i) {
 214                if (gp[i]) {
 215                        dev_info(&agp_bridge->dev->dev,
 216                                 "u3_insert_memory: entry 0x%x occupied (%x)\n",
 217                                 i, gp[i]);
 218                        return -EBUSY;
 219                }
 220        }
 221
 222        for (i = 0; i < mem->page_count; i++) {
 223                gp[i] = (page_to_phys(mem->pages[i]) >> PAGE_SHIFT) | 0x80000000UL;
 224                flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])),
 225                                   (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000);
 226        }
 227        mb();
 228        uninorth_tlbflush(mem);
 229
 230        return 0;
 231}
 232
 233int u3_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
 234{
 235        size_t i;
 236        u32 *gp;
 237
 238        if (type != 0 || mem->type != 0)
 239                /* We know nothing of memory types */
 240                return -EINVAL;
 241
 242        gp = (u32 *) &agp_bridge->gatt_table[pg_start];
 243        for (i = 0; i < mem->page_count; ++i)
 244                gp[i] = 0;
 245        mb();
 246        uninorth_tlbflush(mem);
 247
 248        return 0;
 249}
 250
 251static void uninorth_agp_enable(struct agp_bridge_data *bridge, u32 mode)
 252{
 253        u32 command, scratch, status;
 254        int timeout;
 255
 256        pci_read_config_dword(bridge->dev,
 257                              bridge->capndx + PCI_AGP_STATUS,
 258                              &status);
 259
 260        command = agp_collect_device_status(bridge, mode, status);
 261        command |= PCI_AGP_COMMAND_AGP;
 262
 263        if (uninorth_rev == 0x21) {
 264                /*
 265                 * Darwin disable AGP 4x on this revision, thus we
 266                 * may assume it's broken. This is an AGP2 controller.
 267                 */
 268                command &= ~AGPSTAT2_4X;
 269        }
 270
 271        if ((uninorth_rev >= 0x30) && (uninorth_rev <= 0x33)) {
 272                /*
 273                 * We need to set REQ_DEPTH to 7 for U3 versions 1.0, 2.1,
 274                 * 2.2 and 2.3, Darwin do so.
 275                 */
 276                if ((command >> AGPSTAT_RQ_DEPTH_SHIFT) > 7)
 277                        command = (command & ~AGPSTAT_RQ_DEPTH)
 278                                | (7 << AGPSTAT_RQ_DEPTH_SHIFT);
 279        }
 280
 281        uninorth_tlbflush(NULL);
 282
 283        timeout = 0;
 284        do {
 285                pci_write_config_dword(bridge->dev,
 286                                       bridge->capndx + PCI_AGP_COMMAND,
 287                                       command);
 288                pci_read_config_dword(bridge->dev,
 289                                      bridge->capndx + PCI_AGP_COMMAND,
 290                                       &scratch);
 291        } while ((scratch & PCI_AGP_COMMAND_AGP) == 0 && ++timeout < 1000);
 292        if ((scratch & PCI_AGP_COMMAND_AGP) == 0)
 293                dev_err(&bridge->dev->dev, "can't write UniNorth AGP "
 294                        "command register\n");
 295
 296        if (uninorth_rev >= 0x30) {
 297                /* This is an AGP V3 */
 298                agp_device_command(command, (status & AGPSTAT_MODE_3_0) != 0);
 299        } else {
 300                /* AGP V2 */
 301                agp_device_command(command, false);
 302        }
 303
 304        uninorth_tlbflush(NULL);
 305}
 306
 307#ifdef CONFIG_PM
 308/*
 309 * These Power Management routines are _not_ called by the normal PCI PM layer,
 310 * but directly by the video driver through function pointers in the device
 311 * tree.
 312 */
 313static int agp_uninorth_suspend(struct pci_dev *pdev)
 314{
 315        struct agp_bridge_data *bridge;
 316        u32 cmd;
 317        u8 agp;
 318        struct pci_dev *device = NULL;
 319
 320        bridge = agp_find_bridge(pdev);
 321        if (bridge == NULL)
 322                return -ENODEV;
 323
 324        /* Only one suspend supported */
 325        if (bridge->dev_private_data)
 326                return 0;
 327
 328        /* turn off AGP on the video chip, if it was enabled */
 329        for_each_pci_dev(device) {
 330                /* Don't touch the bridge yet, device first */
 331                if (device == pdev)
 332                        continue;
 333                /* Only deal with devices on the same bus here, no Mac has a P2P
 334                 * bridge on the AGP port, and mucking around the entire PCI
 335                 * tree is source of problems on some machines because of a bug
 336                 * in some versions of pci_find_capability() when hitting a dead
 337                 * device
 338                 */
 339                if (device->bus != pdev->bus)
 340                        continue;
 341                agp = pci_find_capability(device, PCI_CAP_ID_AGP);
 342                if (!agp)
 343                        continue;
 344                pci_read_config_dword(device, agp + PCI_AGP_COMMAND, &cmd);
 345                if (!(cmd & PCI_AGP_COMMAND_AGP))
 346                        continue;
 347                dev_info(&pdev->dev, "disabling AGP on device %s\n",
 348                         pci_name(device));
 349                cmd &= ~PCI_AGP_COMMAND_AGP;
 350                pci_write_config_dword(device, agp + PCI_AGP_COMMAND, cmd);
 351        }
 352
 353        /* turn off AGP on the bridge */
 354        agp = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 355        pci_read_config_dword(pdev, agp + PCI_AGP_COMMAND, &cmd);
 356        bridge->dev_private_data = (void *)(long)cmd;
 357        if (cmd & PCI_AGP_COMMAND_AGP) {
 358                dev_info(&pdev->dev, "disabling AGP on bridge\n");
 359                cmd &= ~PCI_AGP_COMMAND_AGP;
 360                pci_write_config_dword(pdev, agp + PCI_AGP_COMMAND, cmd);
 361        }
 362        /* turn off the GART */
 363        uninorth_cleanup();
 364
 365        return 0;
 366}
 367
 368static int agp_uninorth_resume(struct pci_dev *pdev)
 369{
 370        struct agp_bridge_data *bridge;
 371        u32 command;
 372
 373        bridge = agp_find_bridge(pdev);
 374        if (bridge == NULL)
 375                return -ENODEV;
 376
 377        command = (long)bridge->dev_private_data;
 378        bridge->dev_private_data = NULL;
 379        if (!(command & PCI_AGP_COMMAND_AGP))
 380                return 0;
 381
 382        uninorth_agp_enable(bridge, command);
 383
 384        return 0;
 385}
 386#endif /* CONFIG_PM */
 387
 388static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 389{
 390        char *table;
 391        char *table_end;
 392        int size;
 393        int page_order;
 394        int num_entries;
 395        int i;
 396        void *temp;
 397        struct page *page;
 398        struct page **pages;
 399
 400        /* We can't handle 2 level gatt's */
 401        if (bridge->driver->size_type == LVL2_APER_SIZE)
 402                return -EINVAL;
 403
 404        table = NULL;
 405        i = bridge->aperture_size_idx;
 406        temp = bridge->current_size;
 407        size = page_order = num_entries = 0;
 408
 409        do {
 410                size = A_SIZE_32(temp)->size;
 411                page_order = A_SIZE_32(temp)->page_order;
 412                num_entries = A_SIZE_32(temp)->num_entries;
 413
 414                table = (char *) __get_free_pages(GFP_KERNEL, page_order);
 415
 416                if (table == NULL) {
 417                        i++;
 418                        bridge->current_size = A_IDX32(bridge);
 419                } else {
 420                        bridge->aperture_size_idx = i;
 421                }
 422        } while (!table && (i < bridge->driver->num_aperture_sizes));
 423
 424        if (table == NULL)
 425                return -ENOMEM;
 426
 427        pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
 428        if (pages == NULL)
 429                goto enomem;
 430
 431        table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 432
 433        for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
 434             page++, i++) {
 435                SetPageReserved(page);
 436                pages[i] = page;
 437        }
 438
 439        bridge->gatt_table_real = (u32 *) table;
 440        /* Need to clear out any dirty data still sitting in caches */
 441        flush_dcache_range((unsigned long)table,
 442                           (unsigned long)(table_end + PAGE_SIZE));
 443        bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
 444
 445        if (bridge->gatt_table == NULL)
 446                goto enomem;
 447
 448        bridge->gatt_bus_addr = virt_to_phys(table);
 449
 450        for (i = 0; i < num_entries; i++)
 451                bridge->gatt_table[i] = 0;
 452
 453        return 0;
 454
 455enomem:
 456        kfree(pages);
 457        if (table)
 458                free_pages((unsigned long)table, page_order);
 459        return -ENOMEM;
 460}
 461
 462static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
 463{
 464        int page_order;
 465        char *table, *table_end;
 466        void *temp;
 467        struct page *page;
 468
 469        temp = bridge->current_size;
 470        page_order = A_SIZE_32(temp)->page_order;
 471
 472        /* Do not worry about freeing memory, because if this is
 473         * called, then all agp memory is deallocated and removed
 474         * from the table.
 475         */
 476
 477        vunmap(bridge->gatt_table);
 478        table = (char *) bridge->gatt_table_real;
 479        table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 480
 481        for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 482                ClearPageReserved(page);
 483
 484        free_pages((unsigned long) bridge->gatt_table_real, page_order);
 485
 486        return 0;
 487}
 488
 489void null_cache_flush(void)
 490{
 491        mb();
 492}
 493
 494/* Setup function */
 495
 496static const struct aper_size_info_32 uninorth_sizes[] =
 497{
 498        {256, 65536, 6, 64},
 499        {128, 32768, 5, 32},
 500        {64, 16384, 4, 16},
 501        {32, 8192, 3, 8},
 502        {16, 4096, 2, 4},
 503        {8, 2048, 1, 2},
 504        {4, 1024, 0, 1}
 505};
 506
 507/*
 508 * Not sure that u3 supports that high aperture sizes but it
 509 * would strange if it did not :)
 510 */
 511static const struct aper_size_info_32 u3_sizes[] =
 512{
 513        {512, 131072, 7, 128},
 514        {256, 65536, 6, 64},
 515        {128, 32768, 5, 32},
 516        {64, 16384, 4, 16},
 517        {32, 8192, 3, 8},
 518        {16, 4096, 2, 4},
 519        {8, 2048, 1, 2},
 520        {4, 1024, 0, 1}
 521};
 522
 523const struct agp_bridge_driver uninorth_agp_driver = {
 524        .owner                  = THIS_MODULE,
 525        .aperture_sizes         = (void *)uninorth_sizes,
 526        .size_type              = U32_APER_SIZE,
 527        .num_aperture_sizes     = ARRAY_SIZE(uninorth_sizes),
 528        .configure              = uninorth_configure,
 529        .fetch_size             = uninorth_fetch_size,
 530        .cleanup                = uninorth_cleanup,
 531        .tlb_flush              = uninorth_tlbflush,
 532        .mask_memory            = agp_generic_mask_memory,
 533        .masks                  = NULL,
 534        .cache_flush            = null_cache_flush,
 535        .agp_enable             = uninorth_agp_enable,
 536        .create_gatt_table      = uninorth_create_gatt_table,
 537        .free_gatt_table        = uninorth_free_gatt_table,
 538        .insert_memory          = uninorth_insert_memory,
 539        .remove_memory          = agp_generic_remove_memory,
 540        .alloc_by_type          = agp_generic_alloc_by_type,
 541        .free_by_type           = agp_generic_free_by_type,
 542        .agp_alloc_page         = agp_generic_alloc_page,
 543        .agp_alloc_pages        = agp_generic_alloc_pages,
 544        .agp_destroy_page       = agp_generic_destroy_page,
 545        .agp_destroy_pages      = agp_generic_destroy_pages,
 546        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 547        .cant_use_aperture      = true,
 548};
 549
 550const struct agp_bridge_driver u3_agp_driver = {
 551        .owner                  = THIS_MODULE,
 552        .aperture_sizes         = (void *)u3_sizes,
 553        .size_type              = U32_APER_SIZE,
 554        .num_aperture_sizes     = ARRAY_SIZE(u3_sizes),
 555        .configure              = uninorth_configure,
 556        .fetch_size             = uninorth_fetch_size,
 557        .cleanup                = uninorth_cleanup,
 558        .tlb_flush              = uninorth_tlbflush,
 559        .mask_memory            = agp_generic_mask_memory,
 560        .masks                  = NULL,
 561        .cache_flush            = null_cache_flush,
 562        .agp_enable             = uninorth_agp_enable,
 563        .create_gatt_table      = uninorth_create_gatt_table,
 564        .free_gatt_table        = uninorth_free_gatt_table,
 565        .insert_memory          = u3_insert_memory,
 566        .remove_memory          = u3_remove_memory,
 567        .alloc_by_type          = agp_generic_alloc_by_type,
 568        .free_by_type           = agp_generic_free_by_type,
 569        .agp_alloc_page         = agp_generic_alloc_page,
 570        .agp_alloc_pages        = agp_generic_alloc_pages,
 571        .agp_destroy_page       = agp_generic_destroy_page,
 572        .agp_destroy_pages      = agp_generic_destroy_pages,
 573        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 574        .cant_use_aperture      = true,
 575        .needs_scratch_page     = true,
 576};
 577
 578static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
 579        {
 580                .device_id      = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
 581                .chipset_name   = "UniNorth",
 582        },
 583        {
 584                .device_id      = PCI_DEVICE_ID_APPLE_UNI_N_AGP_P,
 585                .chipset_name   = "UniNorth/Pangea",
 586        },
 587        {
 588                .device_id      = PCI_DEVICE_ID_APPLE_UNI_N_AGP15,
 589                .chipset_name   = "UniNorth 1.5",
 590        },
 591        {
 592                .device_id      = PCI_DEVICE_ID_APPLE_UNI_N_AGP2,
 593                .chipset_name   = "UniNorth 2",
 594        },
 595        {
 596                .device_id      = PCI_DEVICE_ID_APPLE_U3_AGP,
 597                .chipset_name   = "U3",
 598        },
 599        {
 600                .device_id      = PCI_DEVICE_ID_APPLE_U3L_AGP,
 601                .chipset_name   = "U3L",
 602        },
 603        {
 604                .device_id      = PCI_DEVICE_ID_APPLE_U3H_AGP,
 605                .chipset_name   = "U3H",
 606        },
 607        {
 608                .device_id      = PCI_DEVICE_ID_APPLE_IPID2_AGP,
 609                .chipset_name   = "UniNorth/Intrepid2",
 610        },
 611};
 612
 613static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
 614                                        const struct pci_device_id *ent)
 615{
 616        struct agp_device_ids *devs = uninorth_agp_device_ids;
 617        struct agp_bridge_data *bridge;
 618        struct device_node *uninorth_node;
 619        u8 cap_ptr;
 620        int j;
 621
 622        cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
 623        if (cap_ptr == 0)
 624                return -ENODEV;
 625
 626        /* probe for known chipsets */
 627        for (j = 0; devs[j].chipset_name != NULL; ++j) {
 628                if (pdev->device == devs[j].device_id) {
 629                        dev_info(&pdev->dev, "Apple %s chipset\n",
 630                                 devs[j].chipset_name);
 631                        goto found;
 632                }
 633        }
 634
 635        dev_err(&pdev->dev, "unsupported Apple chipset [%04x/%04x]\n",
 636                pdev->vendor, pdev->device);
 637        return -ENODEV;
 638
 639 found:
 640        /* Set revision to 0 if we could not read it. */
 641        uninorth_rev = 0;
 642        is_u3 = 0;
 643        /* Locate core99 Uni-N */
 644        uninorth_node = of_find_node_by_name(NULL, "uni-n");
 645        /* Locate G5 u3 */
 646        if (uninorth_node == NULL) {
 647                is_u3 = 1;
 648                uninorth_node = of_find_node_by_name(NULL, "u3");
 649        }
 650        if (uninorth_node) {
 651                const int *revprop = of_get_property(uninorth_node,
 652                                "device-rev", NULL);
 653                if (revprop != NULL)
 654                        uninorth_rev = *revprop & 0x3f;
 655                of_node_put(uninorth_node);
 656        }
 657
 658#ifdef CONFIG_PM
 659        /* Inform platform of our suspend/resume caps */
 660        pmac_register_agp_pm(pdev, agp_uninorth_suspend, agp_uninorth_resume);
 661#endif
 662
 663        /* Allocate & setup our driver */
 664        bridge = agp_alloc_bridge();
 665        if (!bridge)
 666                return -ENOMEM;
 667
 668        if (is_u3)
 669                bridge->driver = &u3_agp_driver;
 670        else
 671                bridge->driver = &uninorth_agp_driver;
 672
 673        bridge->dev = pdev;
 674        bridge->capndx = cap_ptr;
 675        bridge->flags = AGP_ERRATA_FASTWRITES;
 676
 677        /* Fill in the mode register */
 678        pci_read_config_dword(pdev, cap_ptr+PCI_AGP_STATUS, &bridge->mode);
 679
 680        pci_set_drvdata(pdev, bridge);
 681        return agp_add_bridge(bridge);
 682}
 683
 684static void __devexit agp_uninorth_remove(struct pci_dev *pdev)
 685{
 686        struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 687
 688#ifdef CONFIG_PM
 689        /* Inform platform of our suspend/resume caps */
 690        pmac_register_agp_pm(pdev, NULL, NULL);
 691#endif
 692
 693        agp_remove_bridge(bridge);
 694        agp_put_bridge(bridge);
 695}
 696
 697static struct pci_device_id agp_uninorth_pci_table[] = {
 698        {
 699        .class          = (PCI_CLASS_BRIDGE_HOST << 8),
 700        .class_mask     = ~0,
 701        .vendor         = PCI_VENDOR_ID_APPLE,
 702        .device         = PCI_ANY_ID,
 703        .subvendor      = PCI_ANY_ID,
 704        .subdevice      = PCI_ANY_ID,
 705        },
 706        { }
 707};
 708
 709MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table);
 710
 711static struct pci_driver agp_uninorth_pci_driver = {
 712        .name           = "agpgart-uninorth",
 713        .id_table       = agp_uninorth_pci_table,
 714        .probe          = agp_uninorth_probe,
 715        .remove         = agp_uninorth_remove,
 716};
 717
 718static int __init agp_uninorth_init(void)
 719{
 720        if (agp_off)
 721                return -EINVAL;
 722        return pci_register_driver(&agp_uninorth_pci_driver);
 723}
 724
 725static void __exit agp_uninorth_cleanup(void)
 726{
 727        pci_unregister_driver(&agp_uninorth_pci_driver);
 728}
 729
 730module_init(agp_uninorth_init);
 731module_exit(agp_uninorth_cleanup);
 732
 733module_param(aperture, charp, 0);
 734MODULE_PARM_DESC(aperture,
 735                 "Aperture size, must be power of two between 4MB and an\n"
 736                 "\t\tupper limit specific to the UniNorth revision.\n"
 737                 "\t\tDefault: " DEFAULT_APERTURE_STRING "M");
 738
 739MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
 740MODULE_LICENSE("GPL");
 741