linux/arch/mn10300/unit-asb2305/pci.c
<<
>>
Prefs
   1/* ASB2305 PCI support
   2 *
   3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 * Derived from arch/i386/kernel/pci-pc.c
   6 *      (c) 1999--2000 Martin Mares <mj@suse.cz>
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public Licence
  10 * as published by the Free Software Foundation; either version
  11 * 2 of the Licence, or (at your option) any later version.
  12 */
  13#include <linux/types.h>
  14#include <linux/kernel.h>
  15#include <linux/sched.h>
  16#include <linux/pci.h>
  17#include <linux/init.h>
  18#include <linux/ioport.h>
  19#include <linux/delay.h>
  20#include <linux/irq.h>
  21#include <asm/io.h>
  22#include <asm/irq.h>
  23#include "pci-asb2305.h"
  24
  25unsigned int pci_probe = 1;
  26
  27struct pci_ops *pci_root_ops;
  28
  29/*
  30 * The accessible PCI window does not cover the entire CPU address space, but
  31 * there are devices we want to access outside of that window, so we need to
  32 * insert specific PCI bus resources instead of using the platform-level bus
  33 * resources directly for the PCI root bus.
  34 *
  35 * These are configured and inserted by pcibios_init().
  36 */
  37static struct resource pci_ioport_resource = {
  38        .name   = "PCI IO",
  39        .start  = 0xbe000000,
  40        .end    = 0xbe03ffff,
  41        .flags  = IORESOURCE_IO,
  42};
  43
  44static struct resource pci_iomem_resource = {
  45        .name   = "PCI mem",
  46        .start  = 0xb8000000,
  47        .end    = 0xbbffffff,
  48        .flags  = IORESOURCE_MEM,
  49};
  50
  51/*
  52 * Functions for accessing PCI configuration space
  53 */
  54
  55#define CONFIG_CMD(bus, devfn, where) \
  56        (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
  57
  58#define MEM_PAGING_REG  (*(volatile __u32 *) 0xBFFFFFF4)
  59#define CONFIG_ADDRESS  (*(volatile __u32 *) 0xBFFFFFF8)
  60#define CONFIG_DATAL(X) (*(volatile __u32 *) 0xBFFFFFFC)
  61#define CONFIG_DATAW(X) (*(volatile __u16 *) (0xBFFFFFFC + ((X) & 2)))
  62#define CONFIG_DATAB(X) (*(volatile __u8  *) (0xBFFFFFFC + ((X) & 3)))
  63
  64#define BRIDGEREGB(X)   (*(volatile __u8  *) (0xBE040000 + (X)))
  65#define BRIDGEREGW(X)   (*(volatile __u16 *) (0xBE040000 + (X)))
  66#define BRIDGEREGL(X)   (*(volatile __u32 *) (0xBE040000 + (X)))
  67
  68static inline int __query(const struct pci_bus *bus, unsigned int devfn)
  69{
  70#if 0
  71        return bus->number == 0 && (devfn == PCI_DEVFN(0, 0));
  72        return bus->number == 1;
  73        return bus->number == 0 &&
  74                (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(3, 0));
  75#endif
  76        return 1;
  77}
  78
  79/*
  80 *
  81 */
  82static int pci_ampci_read_config_byte(struct pci_bus *bus, unsigned int devfn,
  83                                      int where, u32 *_value)
  84{
  85        u32 rawval, value;
  86
  87        if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
  88                value = BRIDGEREGB(where);
  89                __pcbdebug("=> %02hx", &BRIDGEREGL(where), value);
  90        } else {
  91                CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where);
  92                rawval = CONFIG_ADDRESS;
  93                value = CONFIG_DATAB(where);
  94                if (__query(bus, devfn))
  95                        __pcidebug("=> %02hx", bus, devfn, where, value);
  96        }
  97
  98        *_value = value;
  99        return PCIBIOS_SUCCESSFUL;
 100}
 101
 102static int pci_ampci_read_config_word(struct pci_bus *bus, unsigned int devfn,
 103                                      int where, u32 *_value)
 104{
 105        u32 rawval, value;
 106
 107        if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
 108                value = BRIDGEREGW(where);
 109                __pcbdebug("=> %04hx", &BRIDGEREGL(where), value);
 110        } else {
 111                CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where);
 112                rawval = CONFIG_ADDRESS;
 113                value = CONFIG_DATAW(where);
 114                if (__query(bus, devfn))
 115                        __pcidebug("=> %04hx", bus, devfn, where, value);
 116        }
 117
 118        *_value = value;
 119        return PCIBIOS_SUCCESSFUL;
 120}
 121
 122static int pci_ampci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
 123                                       int where, u32 *_value)
 124{
 125        u32 rawval, value;
 126
 127        if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
 128                value = BRIDGEREGL(where);
 129                __pcbdebug("=> %08x", &BRIDGEREGL(where), value);
 130        } else {
 131                CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where);
 132                rawval = CONFIG_ADDRESS;
 133                value = CONFIG_DATAL(where);
 134                if (__query(bus, devfn))
 135                        __pcidebug("=> %08x", bus, devfn, where, value);
 136        }
 137
 138        *_value = value;
 139        return PCIBIOS_SUCCESSFUL;
 140}
 141
 142static int pci_ampci_write_config_byte(struct pci_bus *bus, unsigned int devfn,
 143                                       int where, u8 value)
 144{
 145        u32 rawval;
 146
 147        if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
 148                __pcbdebug("<= %02x", &BRIDGEREGB(where), value);
 149                BRIDGEREGB(where) = value;
 150        } else {
 151                if (bus->number == 0 &&
 152                    (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(3, 0))
 153                    )
 154                        __pcidebug("<= %02x", bus, devfn, where, value);
 155                CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where);
 156                rawval = CONFIG_ADDRESS;
 157                CONFIG_DATAB(where) = value;
 158        }
 159        return PCIBIOS_SUCCESSFUL;
 160}
 161
 162static int pci_ampci_write_config_word(struct pci_bus *bus, unsigned int devfn,
 163                                       int where, u16 value)
 164{
 165        u32 rawval;
 166
 167        if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
 168                __pcbdebug("<= %04hx", &BRIDGEREGW(where), value);
 169                BRIDGEREGW(where) = value;
 170        } else {
 171                if (__query(bus, devfn))
 172                        __pcidebug("<= %04hx", bus, devfn, where, value);
 173                CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where);
 174                rawval = CONFIG_ADDRESS;
 175                CONFIG_DATAW(where) = value;
 176        }
 177        return PCIBIOS_SUCCESSFUL;
 178}
 179
 180static int pci_ampci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
 181                                        int where, u32 value)
 182{
 183        u32 rawval;
 184
 185        if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) {
 186                __pcbdebug("<= %08x", &BRIDGEREGL(where), value);
 187                BRIDGEREGL(where) = value;
 188        } else {
 189                if (__query(bus, devfn))
 190                        __pcidebug("<= %08x", bus, devfn, where, value);
 191                CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where);
 192                rawval = CONFIG_ADDRESS;
 193                CONFIG_DATAL(where) = value;
 194        }
 195        return PCIBIOS_SUCCESSFUL;
 196}
 197
 198static int pci_ampci_read_config(struct pci_bus *bus, unsigned int devfn,
 199                                 int where, int size, u32 *val)
 200{
 201        switch (size) {
 202        case 1:
 203                return pci_ampci_read_config_byte(bus, devfn, where, val);
 204        case 2:
 205                return pci_ampci_read_config_word(bus, devfn, where, val);
 206        case 4:
 207                return pci_ampci_read_config_dword(bus, devfn, where, val);
 208        default:
 209                BUG();
 210                return -EOPNOTSUPP;
 211        }
 212}
 213
 214static int pci_ampci_write_config(struct pci_bus *bus, unsigned int devfn,
 215                                  int where, int size, u32 val)
 216{
 217        switch (size) {
 218        case 1:
 219                return pci_ampci_write_config_byte(bus, devfn, where, val);
 220        case 2:
 221                return pci_ampci_write_config_word(bus, devfn, where, val);
 222        case 4:
 223                return pci_ampci_write_config_dword(bus, devfn, where, val);
 224        default:
 225                BUG();
 226                return -EOPNOTSUPP;
 227        }
 228}
 229
 230static struct pci_ops pci_direct_ampci = {
 231        .read = pci_ampci_read_config,
 232        .write = pci_ampci_write_config,
 233};
 234
 235/*
 236 * Before we decide to use direct hardware access mechanisms, we try to do some
 237 * trivial checks to ensure it at least _seems_ to be working -- we just test
 238 * whether bus 00 contains a host bridge (this is similar to checking
 239 * techniques used in XFree86, but ours should be more reliable since we
 240 * attempt to make use of direct access hints provided by the PCI BIOS).
 241 *
 242 * This should be close to trivial, but it isn't, because there are buggy
 243 * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
 244 */
 245static int __init pci_sanity_check(struct pci_ops *o)
 246{
 247        struct pci_bus bus;             /* Fake bus and device */
 248        u32 x;
 249
 250        bus.number = 0;
 251
 252        if ((!o->read(&bus, 0, PCI_CLASS_DEVICE, 2, &x) &&
 253             (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
 254            (!o->read(&bus, 0, PCI_VENDOR_ID, 2, &x) &&
 255             (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
 256                return 1;
 257
 258        printk(KERN_ERR "PCI: Sanity check failed\n");
 259        return 0;
 260}
 261
 262static int __init pci_check_direct(void)
 263{
 264        unsigned long flags;
 265
 266        local_irq_save(flags);
 267
 268        /*
 269         * Check if access works.
 270         */
 271        if (pci_sanity_check(&pci_direct_ampci)) {
 272                local_irq_restore(flags);
 273                printk(KERN_INFO "PCI: Using configuration ampci\n");
 274                request_mem_region(0xBE040000, 256, "AMPCI bridge");
 275                request_mem_region(0xBFFFFFF4, 12, "PCI ampci");
 276                request_mem_region(0xBC000000, 32 * 1024 * 1024, "PCI SRAM");
 277                return 0;
 278        }
 279
 280        local_irq_restore(flags);
 281        return -ENODEV;
 282}
 283
 284static void pcibios_fixup_device_resources(struct pci_dev *dev)
 285{
 286        int idx;
 287
 288        if (!dev->bus)
 289                return;
 290
 291        for (idx = 0; idx < PCI_BRIDGE_RESOURCES; idx++) {
 292                struct resource *r = &dev->resource[idx];
 293
 294                if (!r->flags || r->parent || !r->start)
 295                        continue;
 296
 297                pci_claim_resource(dev, idx);
 298        }
 299}
 300
 301static void pcibios_fixup_bridge_resources(struct pci_dev *dev)
 302{
 303        int idx;
 304
 305        if (!dev->bus)
 306                return;
 307
 308        for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
 309                struct resource *r = &dev->resource[idx];
 310
 311                if (!r->flags || r->parent || !r->start)
 312                        continue;
 313
 314                pci_claim_bridge_resource(dev, idx);
 315        }
 316}
 317
 318/*
 319 *  Called after each bus is probed, but before its children
 320 *  are examined.
 321 */
 322void pcibios_fixup_bus(struct pci_bus *bus)
 323{
 324        struct pci_dev *dev;
 325
 326        if (bus->self) {
 327                pci_read_bridge_bases(bus);
 328                pcibios_fixup_bridge_resources(bus->self);
 329        }
 330
 331        list_for_each_entry(dev, &bus->devices, bus_list)
 332                pcibios_fixup_device_resources(dev);
 333}
 334
 335/*
 336 * Initialization. Try all known PCI access methods. Note that we support
 337 * using both PCI BIOS and direct access: in such cases, we use I/O ports
 338 * to access config space, but we still keep BIOS order of cards to be
 339 * compatible with 2.0.X. This should go away some day.
 340 */
 341static int __init pcibios_init(void)
 342{
 343        resource_size_t io_offset, mem_offset;
 344        LIST_HEAD(resources);
 345        struct pci_bus *bus;
 346
 347        ioport_resource.start   = 0xA0000000;
 348        ioport_resource.end     = 0xDFFFFFFF;
 349        iomem_resource.start    = 0xA0000000;
 350        iomem_resource.end      = 0xDFFFFFFF;
 351
 352        if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0)
 353                panic("Unable to insert PCI IOMEM resource\n");
 354        if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0)
 355                panic("Unable to insert PCI IOPORT resource\n");
 356
 357        if (!pci_probe)
 358                return 0;
 359
 360        if (pci_check_direct() < 0) {
 361                printk(KERN_WARNING "PCI: No PCI bus detected\n");
 362                return 0;
 363        }
 364
 365        printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
 366               MEM_PAGING_REG);
 367
 368        io_offset = pci_ioport_resource.start -
 369            (pci_ioport_resource.start & 0x00ffffff);
 370        mem_offset = pci_iomem_resource.start -
 371            ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG);
 372
 373        pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset);
 374        pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset);
 375        bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources);
 376        if (!bus)
 377                return 0;
 378
 379        pcibios_irq_init();
 380        pcibios_fixup_irqs();
 381        pcibios_resource_survey();
 382        pci_bus_add_devices(bus);
 383        return 0;
 384}
 385
 386arch_initcall(pcibios_init);
 387
 388char *__init pcibios_setup(char *str)
 389{
 390        if (!strcmp(str, "off")) {
 391                pci_probe = 0;
 392                return NULL;
 393        }
 394
 395        return str;
 396}
 397
 398int pcibios_enable_device(struct pci_dev *dev, int mask)
 399{
 400        int err;
 401
 402        err = pci_enable_resources(dev, mask);
 403        if (err == 0)
 404                pcibios_enable_irq(dev);
 405        return err;
 406}
 407
 408/*
 409 * disable the ethernet chipset
 410 */
 411static void __init unit_disable_pcnet(struct pci_bus *bus, struct pci_ops *o)
 412{
 413        u32 x;
 414
 415        bus->number = 0;
 416
 417        o->read (bus, PCI_DEVFN(2, 0), PCI_VENDOR_ID,           4, &x);
 418        o->read (bus, PCI_DEVFN(2, 0), PCI_COMMAND,             2, &x);
 419        x |= PCI_COMMAND_MASTER |
 420                PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
 421                PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
 422        o->write(bus, PCI_DEVFN(2, 0), PCI_COMMAND,             2, x);
 423        o->read (bus, PCI_DEVFN(2, 0), PCI_COMMAND,             2, &x);
 424        o->write(bus, PCI_DEVFN(2, 0), PCI_BASE_ADDRESS_0,      4, 0x00030001);
 425        o->read (bus, PCI_DEVFN(2, 0), PCI_BASE_ADDRESS_0,      4, &x);
 426
 427#define RDP (*(volatile u32 *) 0xBE030010)
 428#define RAP (*(volatile u32 *) 0xBE030014)
 429#define __set_RAP(X) do { RAP = (X); x = RAP; } while (0)
 430#define __set_RDP(X) do { RDP = (X); x = RDP; } while (0)
 431#define __get_RDP() ({ RDP & 0xffff; })
 432
 433        __set_RAP(0);
 434        __set_RDP(0x0004);      /* CSR0 = STOP */
 435
 436        __set_RAP(88);          /* check CSR88 indicates an Am79C973 */
 437        BUG_ON(__get_RDP() != 0x5003);
 438
 439        for (x = 0; x < 100; x++)
 440                asm volatile("nop");
 441
 442        __set_RDP(0x0004);      /* CSR0 = STOP */
 443}
 444
 445/*
 446 * initialise the unit hardware
 447 */
 448asmlinkage void __init unit_pci_init(void)
 449{
 450        struct pci_bus bus;             /* Fake bus and device */
 451        struct pci_ops *o = &pci_direct_ampci;
 452        u32 x;
 453
 454        set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_PCI_IRQ_LEVEL));
 455
 456        memset(&bus, 0, sizeof(bus));
 457
 458        MEM_PAGING_REG = 0xE8000000;
 459
 460        /* we need to set up the bridge _now_ or we won't be able to access the
 461         * PCI config registers
 462         */
 463        BRIDGEREGW(PCI_COMMAND) |=
 464                PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
 465                PCI_COMMAND_MEMORY | PCI_COMMAND_IO | PCI_COMMAND_MASTER;
 466        BRIDGEREGW(PCI_STATUS)          = 0xF800;
 467        BRIDGEREGB(PCI_LATENCY_TIMER)   = 0x10;
 468        BRIDGEREGL(PCI_BASE_ADDRESS_0)  = 0x80000000;
 469        BRIDGEREGB(PCI_INTERRUPT_LINE)  = 1;
 470        BRIDGEREGL(0x48)                = 0x98000000;   /* AMPCI base addr */
 471        BRIDGEREGB(0x41)                = 0x00;         /* secondary bus
 472                                                         * number */
 473        BRIDGEREGB(0x42)                = 0x01;         /* subordinate bus
 474                                                         * number */
 475        BRIDGEREGB(0x44)                = 0x01;
 476        BRIDGEREGL(0x50)                = 0x00000001;
 477        BRIDGEREGL(0x58)                = 0x00001002;
 478        BRIDGEREGL(0x5C)                = 0x00000011;
 479
 480        /* we also need to set up the PCI-PCI bridge */
 481        bus.number = 0;
 482
 483        /* IO: 0x00000000-0x00020000 */
 484        o->read (&bus, PCI_DEVFN(3, 0), PCI_COMMAND,            2, &x);
 485        x |= PCI_COMMAND_MASTER |
 486                PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
 487                PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
 488        o->write(&bus, PCI_DEVFN(3, 0), PCI_COMMAND,            2, x);
 489
 490        o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE,            1, &x);
 491        o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE_UPPER16,    4, &x);
 492        o->read (&bus, PCI_DEVFN(3, 0), PCI_MEMORY_BASE,        4, &x);
 493        o->read (&bus, PCI_DEVFN(3, 0), PCI_PREF_MEMORY_BASE,   4, &x);
 494
 495        o->write(&bus, PCI_DEVFN(3, 0), PCI_IO_BASE,            1, 0x01);
 496        o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE,            1, &x);
 497        o->write(&bus, PCI_DEVFN(3, 0), PCI_IO_BASE_UPPER16,    4, 0x00020000);
 498        o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE_UPPER16,    4, &x);
 499        o->write(&bus, PCI_DEVFN(3, 0), PCI_MEMORY_BASE,        4, 0xEBB0EA00);
 500        o->read (&bus, PCI_DEVFN(3, 0), PCI_MEMORY_BASE,        4, &x);
 501        o->write(&bus, PCI_DEVFN(3, 0), PCI_PREF_MEMORY_BASE,   4, 0xE9F0E800);
 502        o->read (&bus, PCI_DEVFN(3, 0), PCI_PREF_MEMORY_BASE,   4, &x);
 503
 504        unit_disable_pcnet(&bus, o);
 505}
 506