linux/arch/x86/pci/mrst.c
<<
>>
Prefs
   1/*
   2 * Moorestown PCI support
   3 *   Copyright (c) 2008 Intel Corporation
   4 *     Jesse Barnes <jesse.barnes@intel.com>
   5 *
   6 * Moorestown has an interesting PCI implementation:
   7 *   - configuration space is memory mapped (as defined by MCFG)
   8 *   - Lincroft devices also have a real, type 1 configuration space
   9 *   - Early Lincroft silicon has a type 1 access bug that will cause
  10 *     a hang if non-existent devices are accessed
  11 *   - some devices have the "fixed BAR" capability, which means
  12 *     they can't be relocated or modified; check for that during
  13 *     BAR sizing
  14 *
  15 * So, we use the MCFG space for all reads and writes, but also send
  16 * Lincroft writes to type 1 space.  But only read/write if the device
  17 * actually exists, otherwise return all 1s for reads and bit bucket
  18 * the writes.
  19 */
  20
  21#include <linux/sched.h>
  22#include <linux/pci.h>
  23#include <linux/ioport.h>
  24#include <linux/init.h>
  25#include <linux/dmi.h>
  26
  27#include <asm/acpi.h>
  28#include <asm/segment.h>
  29#include <asm/io.h>
  30#include <asm/smp.h>
  31#include <asm/pci_x86.h>
  32#include <asm/hw_irq.h>
  33#include <asm/io_apic.h>
  34
  35#define PCIE_CAP_OFFSET 0x100
  36
  37/* Fixed BAR fields */
  38#define PCIE_VNDR_CAP_ID_FIXED_BAR 0x00 /* Fixed BAR (TBD) */
  39#define PCI_FIXED_BAR_0_SIZE    0x04
  40#define PCI_FIXED_BAR_1_SIZE    0x08
  41#define PCI_FIXED_BAR_2_SIZE    0x0c
  42#define PCI_FIXED_BAR_3_SIZE    0x10
  43#define PCI_FIXED_BAR_4_SIZE    0x14
  44#define PCI_FIXED_BAR_5_SIZE    0x1c
  45
  46static int pci_soc_mode = 0;
  47
  48/**
  49 * fixed_bar_cap - return the offset of the fixed BAR cap if found
  50 * @bus: PCI bus
  51 * @devfn: device in question
  52 *
  53 * Look for the fixed BAR cap on @bus and @devfn, returning its offset
  54 * if found or 0 otherwise.
  55 */
  56static int fixed_bar_cap(struct pci_bus *bus, unsigned int devfn)
  57{
  58        int pos;
  59        u32 pcie_cap = 0, cap_data;
  60
  61        pos = PCIE_CAP_OFFSET;
  62
  63        if (!raw_pci_ext_ops)
  64                return 0;
  65
  66        while (pos) {
  67                if (raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
  68                                          devfn, pos, 4, &pcie_cap))
  69                        return 0;
  70
  71                if (PCI_EXT_CAP_ID(pcie_cap) == 0x0000 ||
  72                        PCI_EXT_CAP_ID(pcie_cap) == 0xffff)
  73                        break;
  74
  75                if (PCI_EXT_CAP_ID(pcie_cap) == PCI_EXT_CAP_ID_VNDR) {
  76                        raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
  77                                              devfn, pos + 4, 4, &cap_data);
  78                        if ((cap_data & 0xffff) == PCIE_VNDR_CAP_ID_FIXED_BAR)
  79                                return pos;
  80                }
  81
  82                pos = PCI_EXT_CAP_NEXT(pcie_cap);
  83        }
  84
  85        return 0;
  86}
  87
  88static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
  89                                   int reg, int len, u32 val, int offset)
  90{
  91        u32 size;
  92        unsigned int domain, busnum;
  93        int bar = (reg - PCI_BASE_ADDRESS_0) >> 2;
  94
  95        domain = pci_domain_nr(bus);
  96        busnum = bus->number;
  97
  98        if (val == ~0 && len == 4) {
  99                unsigned long decode;
 100
 101                raw_pci_ext_ops->read(domain, busnum, devfn,
 102                               offset + 8 + (bar * 4), 4, &size);
 103
 104                /* Turn the size into a decode pattern for the sizing code */
 105                if (size) {
 106                        decode = size - 1;
 107                        decode |= decode >> 1;
 108                        decode |= decode >> 2;
 109                        decode |= decode >> 4;
 110                        decode |= decode >> 8;
 111                        decode |= decode >> 16;
 112                        decode++;
 113                        decode = ~(decode - 1);
 114                } else {
 115                        decode = 0;
 116                }
 117
 118                /*
 119                 * If val is all ones, the core code is trying to size the reg,
 120                 * so update the mmconfig space with the real size.
 121                 *
 122                 * Note: this assumes the fixed size we got is a power of two.
 123                 */
 124                return raw_pci_ext_ops->write(domain, busnum, devfn, reg, 4,
 125                                       decode);
 126        }
 127
 128        /* This is some other kind of BAR write, so just do it. */
 129        return raw_pci_ext_ops->write(domain, busnum, devfn, reg, len, val);
 130}
 131
 132/**
 133 * type1_access_ok - check whether to use type 1
 134 * @bus: bus number
 135 * @devfn: device & function in question
 136 *
 137 * If the bus is on a Lincroft chip and it exists, or is not on a Lincroft at
 138 * all, the we can go ahead with any reads & writes.  If it's on a Lincroft,
 139 * but doesn't exist, avoid the access altogether to keep the chip from
 140 * hanging.
 141 */
 142static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
 143{
 144        /* This is a workaround for A0 LNC bug where PCI status register does
 145         * not have new CAP bit set. can not be written by SW either.
 146         *
 147         * PCI header type in real LNC indicates a single function device, this
 148         * will prevent probing other devices under the same function in PCI
 149         * shim. Therefore, use the header type in shim instead.
 150         */
 151        if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
 152                return 0;
 153        if (bus == 0 && (devfn == PCI_DEVFN(2, 0)
 154                                || devfn == PCI_DEVFN(0, 0)
 155                                || devfn == PCI_DEVFN(3, 0)))
 156                return 1;
 157        return 0; /* langwell on others */
 158}
 159
 160static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
 161                    int size, u32 *value)
 162{
 163        if (type1_access_ok(bus->number, devfn, where))
 164                return pci_direct_conf1.read(pci_domain_nr(bus), bus->number,
 165                                        devfn, where, size, value);
 166        return raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
 167                              devfn, where, size, value);
 168}
 169
 170static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
 171                     int size, u32 value)
 172{
 173        int offset;
 174
 175        /* On MRST, there is no PCI ROM BAR, this will cause a subsequent read
 176         * to ROM BAR return 0 then being ignored.
 177         */
 178        if (where == PCI_ROM_ADDRESS)
 179                return 0;
 180
 181        /*
 182         * Devices with fixed BARs need special handling:
 183         *   - BAR sizing code will save, write ~0, read size, restore
 184         *   - so writes to fixed BARs need special handling
 185         *   - other writes to fixed BAR devices should go through mmconfig
 186         */
 187        offset = fixed_bar_cap(bus, devfn);
 188        if (offset &&
 189            (where >= PCI_BASE_ADDRESS_0 && where <= PCI_BASE_ADDRESS_5)) {
 190                return pci_device_update_fixed(bus, devfn, where, size, value,
 191                                               offset);
 192        }
 193
 194        /*
 195         * On Moorestown update both real & mmconfig space
 196         * Note: early Lincroft silicon can't handle type 1 accesses to
 197         *       non-existent devices, so just eat the write in that case.
 198         */
 199        if (type1_access_ok(bus->number, devfn, where))
 200                return pci_direct_conf1.write(pci_domain_nr(bus), bus->number,
 201                                              devfn, where, size, value);
 202        return raw_pci_ext_ops->write(pci_domain_nr(bus), bus->number, devfn,
 203                               where, size, value);
 204}
 205
 206static int mrst_pci_irq_enable(struct pci_dev *dev)
 207{
 208        u8 pin;
 209        struct io_apic_irq_attr irq_attr;
 210
 211        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 212
 213        /* MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to
 214         * IOAPIC RTE entries, so we just enable RTE for the device.
 215         */
 216        irq_attr.ioapic = mp_find_ioapic(dev->irq);
 217        irq_attr.ioapic_pin = dev->irq;
 218        irq_attr.trigger = 1; /* level */
 219        irq_attr.polarity = 1; /* active low */
 220        io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
 221
 222        return 0;
 223}
 224
 225struct pci_ops pci_mrst_ops = {
 226        .read = pci_read,
 227        .write = pci_write,
 228};
 229
 230/**
 231 * pci_mrst_init - installs pci_mrst_ops
 232 *
 233 * Moorestown has an interesting PCI implementation (see above).
 234 * Called when the early platform detection installs it.
 235 */
 236int __init pci_mrst_init(void)
 237{
 238        printk(KERN_INFO "Intel MID platform detected, using MID PCI ops\n");
 239        pci_mmcfg_late_init();
 240        pcibios_enable_irq = mrst_pci_irq_enable;
 241        pci_root_ops = pci_mrst_ops;
 242        pci_soc_mode = 1;
 243        /* Continue with standard init */
 244        return 1;
 245}
 246
 247/* Langwell devices are not true pci devices, they are not subject to 10 ms
 248 * d3 to d0 delay required by pci spec.
 249 */
 250static void pci_d3delay_fixup(struct pci_dev *dev)
 251{
 252        /* PCI fixups are effectively decided compile time. If we have a dual
 253           SoC/non-SoC kernel we don't want to mangle d3 on non SoC devices */
 254        if (!pci_soc_mode)
 255            return;
 256        /* true pci devices in lincroft should allow type 1 access, the rest
 257         * are langwell fake pci devices.
 258         */
 259        if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID))
 260                return;
 261        dev->d3_delay = 0;
 262}
 263DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup);
 264
 265static void mrst_power_off_unused_dev(struct pci_dev *dev)
 266{
 267        pci_set_power_state(dev, PCI_D3hot);
 268}
 269DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0801, mrst_power_off_unused_dev);
 270DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0809, mrst_power_off_unused_dev);
 271DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x080C, mrst_power_off_unused_dev);
 272DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0812, mrst_power_off_unused_dev);
 273DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0815, mrst_power_off_unused_dev);
 274
 275/*
 276 * Langwell devices reside at fixed offsets, don't try to move them.
 277 */
 278static void pci_fixed_bar_fixup(struct pci_dev *dev)
 279{
 280        unsigned long offset;
 281        u32 size;
 282        int i;
 283
 284        if (!pci_soc_mode)
 285                return;
 286
 287        /* Must have extended configuration space */
 288        if (dev->cfg_size < PCIE_CAP_OFFSET + 4)
 289                return;
 290
 291        /* Fixup the BAR sizes for fixed BAR devices and make them unmoveable */
 292        offset = fixed_bar_cap(dev->bus, dev->devfn);
 293        if (!offset || PCI_DEVFN(2, 0) == dev->devfn ||
 294            PCI_DEVFN(2, 2) == dev->devfn)
 295                return;
 296
 297        for (i = 0; i < PCI_ROM_RESOURCE; i++) {
 298                pci_read_config_dword(dev, offset + 8 + (i * 4), &size);
 299                dev->resource[i].end = dev->resource[i].start + size - 1;
 300                dev->resource[i].flags |= IORESOURCE_PCI_FIXED;
 301        }
 302}
 303DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixed_bar_fixup);
 304