linux/arch/powerpc/platforms/cell/celleb_scc_pciex.c
<<
>>
Prefs
   1/*
   2 * Support for Celleb PCI-Express.
   3 *
   4 * (C) Copyright 2007-2008 TOSHIBA CORPORATION
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along
  17 * with this program; if not, write to the Free Software Foundation, Inc.,
  18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19 */
  20
  21#undef DEBUG
  22
  23#include <linux/kernel.h>
  24#include <linux/pci.h>
  25#include <linux/string.h>
  26#include <linux/slab.h>
  27#include <linux/init.h>
  28#include <linux/bootmem.h>
  29#include <linux/delay.h>
  30#include <linux/interrupt.h>
  31
  32#include <asm/io.h>
  33#include <asm/irq.h>
  34#include <asm/iommu.h>
  35#include <asm/byteorder.h>
  36
  37#include "celleb_scc.h"
  38#include "celleb_pci.h"
  39
  40#define PEX_IN(base, off)       in_be32((void __iomem *)(base) + (off))
  41#define PEX_OUT(base, off, data) out_be32((void __iomem *)(base) + (off), (data))
  42
  43static void scc_pciex_io_flush(struct iowa_bus *bus)
  44{
  45        (void)PEX_IN(bus->phb->cfg_addr, PEXDMRDEN0);
  46}
  47
  48/*
  49 * Memory space access to device on PCIEX
  50 */
  51#define PCIEX_MMIO_READ(name, ret)                                      \
  52static ret scc_pciex_##name(const PCI_IO_ADDR addr)                     \
  53{                                                                       \
  54        ret val = __do_##name(addr);                                    \
  55        scc_pciex_io_flush(iowa_mem_find_bus(addr));                    \
  56        return val;                                                     \
  57}
  58
  59#define PCIEX_MMIO_READ_STR(name)                                       \
  60static void scc_pciex_##name(const PCI_IO_ADDR addr, void *buf,         \
  61                             unsigned long count)                       \
  62{                                                                       \
  63        __do_##name(addr, buf, count);                                  \
  64        scc_pciex_io_flush(iowa_mem_find_bus(addr));                    \
  65}
  66
  67PCIEX_MMIO_READ(readb, u8)
  68PCIEX_MMIO_READ(readw, u16)
  69PCIEX_MMIO_READ(readl, u32)
  70PCIEX_MMIO_READ(readq, u64)
  71PCIEX_MMIO_READ(readw_be, u16)
  72PCIEX_MMIO_READ(readl_be, u32)
  73PCIEX_MMIO_READ(readq_be, u64)
  74PCIEX_MMIO_READ_STR(readsb)
  75PCIEX_MMIO_READ_STR(readsw)
  76PCIEX_MMIO_READ_STR(readsl)
  77
  78static void scc_pciex_memcpy_fromio(void *dest, const PCI_IO_ADDR src,
  79                                    unsigned long n)
  80{
  81        __do_memcpy_fromio(dest, src, n);
  82        scc_pciex_io_flush(iowa_mem_find_bus(src));
  83}
  84
  85/*
  86 * I/O port access to devices on PCIEX.
  87 */
  88
  89static inline unsigned long get_bus_address(struct pci_controller *phb,
  90                                            unsigned long port)
  91{
  92        return port - ((unsigned long)(phb->io_base_virt) - _IO_BASE);
  93}
  94
  95static u32 scc_pciex_read_port(struct pci_controller *phb,
  96                               unsigned long port, int size)
  97{
  98        unsigned int byte_enable;
  99        unsigned int cmd, shift;
 100        unsigned long addr;
 101        u32 data, ret;
 102
 103        BUG_ON(((port & 0x3ul) + size) > 4);
 104
 105        addr = get_bus_address(phb, port);
 106        shift = addr & 0x3ul;
 107        byte_enable = ((1 << size) - 1) << shift;
 108        cmd = PEXDCMND_IO_READ | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
 109        PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
 110        PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
 111        data = PEX_IN(phb->cfg_addr, PEXDRDATA);
 112        ret = (data >> (shift * 8)) & (0xFFFFFFFF >> ((4 - size) * 8));
 113
 114        pr_debug("PCIEX:PIO READ:port=0x%lx, addr=0x%lx, size=%d, be=%x,"
 115                 " cmd=%x, data=%x, ret=%x\n", port, addr, size, byte_enable,
 116                 cmd, data, ret);
 117
 118        return ret;
 119}
 120
 121static void scc_pciex_write_port(struct pci_controller *phb,
 122                                 unsigned long port, int size, u32 val)
 123{
 124        unsigned int byte_enable;
 125        unsigned int cmd, shift;
 126        unsigned long addr;
 127        u32 data;
 128
 129        BUG_ON(((port & 0x3ul) + size) > 4);
 130
 131        addr = get_bus_address(phb, port);
 132        shift = addr & 0x3ul;
 133        byte_enable = ((1 << size) - 1) << shift;
 134        cmd = PEXDCMND_IO_WRITE | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
 135        data = (val & (0xFFFFFFFF >> (4 - size) * 8)) << (shift * 8);
 136        PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
 137        PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
 138        PEX_OUT(phb->cfg_addr, PEXDWDATA, data);
 139
 140        pr_debug("PCIEX:PIO WRITE:port=0x%lx, addr=%lx, size=%d, val=%x,"
 141                 " be=%x, cmd=%x, data=%x\n", port, addr, size, val,
 142                 byte_enable, cmd, data);
 143}
 144
 145static u8 __scc_pciex_inb(struct pci_controller *phb, unsigned long port)
 146{
 147        return (u8)scc_pciex_read_port(phb, port, 1);
 148}
 149
 150static u16 __scc_pciex_inw(struct pci_controller *phb, unsigned long port)
 151{
 152        u32 data;
 153        if ((port & 0x3ul) < 3)
 154                data = scc_pciex_read_port(phb, port, 2);
 155        else {
 156                u32 d1 = scc_pciex_read_port(phb, port, 1);
 157                u32 d2 = scc_pciex_read_port(phb, port + 1, 1);
 158                data = d1 | (d2 << 8);
 159        }
 160        return (u16)data;
 161}
 162
 163static u32 __scc_pciex_inl(struct pci_controller *phb, unsigned long port)
 164{
 165        unsigned int mod = port & 0x3ul;
 166        u32 data;
 167        if (mod == 0)
 168                data = scc_pciex_read_port(phb, port, 4);
 169        else {
 170                u32 d1 = scc_pciex_read_port(phb, port, 4 - mod);
 171                u32 d2 = scc_pciex_read_port(phb, port + 1, mod);
 172                data = d1 | (d2 << (mod * 8));
 173        }
 174        return data;
 175}
 176
 177static void __scc_pciex_outb(struct pci_controller *phb,
 178                             u8 val, unsigned long port)
 179{
 180        scc_pciex_write_port(phb, port, 1, (u32)val);
 181}
 182
 183static void __scc_pciex_outw(struct pci_controller *phb,
 184                             u16 val, unsigned long port)
 185{
 186        if ((port & 0x3ul) < 3)
 187                scc_pciex_write_port(phb, port, 2, (u32)val);
 188        else {
 189                u32 d1 = val & 0x000000FF;
 190                u32 d2 = (val & 0x0000FF00) >> 8;
 191                scc_pciex_write_port(phb, port, 1, d1);
 192                scc_pciex_write_port(phb, port + 1, 1, d2);
 193        }
 194}
 195
 196static void __scc_pciex_outl(struct pci_controller *phb,
 197                             u32 val, unsigned long port)
 198{
 199        unsigned int mod = port & 0x3ul;
 200        if (mod == 0)
 201                scc_pciex_write_port(phb, port, 4, val);
 202        else {
 203                u32 d1 = val & (0xFFFFFFFFul >> (mod * 8));
 204                u32 d2 = val >> ((4 - mod) * 8);
 205                scc_pciex_write_port(phb, port, 4 - mod, d1);
 206                scc_pciex_write_port(phb, port + 1, mod, d2);
 207        }
 208}
 209
 210#define PCIEX_PIO_FUNC(size, name)                                      \
 211static u##size scc_pciex_in##name(unsigned long port)                   \
 212{                                                                       \
 213        struct iowa_bus *bus = iowa_pio_find_bus(port);                 \
 214        u##size data = __scc_pciex_in##name(bus->phb, port);            \
 215        scc_pciex_io_flush(bus);                                        \
 216        return data;                                                    \
 217}                                                                       \
 218static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \
 219{                                                                       \
 220        struct iowa_bus *bus = iowa_pio_find_bus(p);                    \
 221        __le##size *dst = b;                                            \
 222        for (; c != 0; c--, dst++)                                      \
 223                *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \
 224        scc_pciex_io_flush(bus);                                        \
 225}                                                                       \
 226static void scc_pciex_out##name(u##size val, unsigned long port)        \
 227{                                                                       \
 228        struct iowa_bus *bus = iowa_pio_find_bus(port);                 \
 229        __scc_pciex_out##name(bus->phb, val, port);                     \
 230}                                                                       \
 231static void scc_pciex_outs##name(unsigned long p, const void *b,        \
 232                                 unsigned long c)                       \
 233{                                                                       \
 234        struct iowa_bus *bus = iowa_pio_find_bus(p);                    \
 235        const __le##size *src = b;                                      \
 236        for (; c != 0; c--, src++)                                      \
 237                __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \
 238}
 239#define __le8 u8
 240#define cpu_to_le8(x) (x)
 241#define le8_to_cpu(x) (x)
 242PCIEX_PIO_FUNC(8, b)
 243PCIEX_PIO_FUNC(16, w)
 244PCIEX_PIO_FUNC(32, l)
 245
 246static struct ppc_pci_io scc_pciex_ops = {
 247        .readb = scc_pciex_readb,
 248        .readw = scc_pciex_readw,
 249        .readl = scc_pciex_readl,
 250        .readq = scc_pciex_readq,
 251        .readw_be = scc_pciex_readw_be,
 252        .readl_be = scc_pciex_readl_be,
 253        .readq_be = scc_pciex_readq_be,
 254        .readsb = scc_pciex_readsb,
 255        .readsw = scc_pciex_readsw,
 256        .readsl = scc_pciex_readsl,
 257        .memcpy_fromio = scc_pciex_memcpy_fromio,
 258        .inb = scc_pciex_inb,
 259        .inw = scc_pciex_inw,
 260        .inl = scc_pciex_inl,
 261        .outb = scc_pciex_outb,
 262        .outw = scc_pciex_outw,
 263        .outl = scc_pciex_outl,
 264        .insb = scc_pciex_insb,
 265        .insw = scc_pciex_insw,
 266        .insl = scc_pciex_insl,
 267        .outsb = scc_pciex_outsb,
 268        .outsw = scc_pciex_outsw,
 269        .outsl = scc_pciex_outsl,
 270};
 271
 272static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data)
 273{
 274        dma_addr_t dummy_page_da;
 275        void *dummy_page_va;
 276
 277        dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
 278        if (!dummy_page_va) {
 279                pr_err("PCIEX:Alloc dummy_page_va failed\n");
 280                return -1;
 281        }
 282
 283        dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va,
 284                                       PAGE_SIZE, DMA_FROM_DEVICE);
 285        if (dma_mapping_error(bus->phb->parent, dummy_page_da)) {
 286                pr_err("PCIEX:Map dummy page failed.\n");
 287                kfree(dummy_page_va);
 288                return -1;
 289        }
 290
 291        PEX_OUT(bus->phb->cfg_addr, PEXDMRDADR0, dummy_page_da);
 292
 293        return 0;
 294}
 295
 296/*
 297 * config space access
 298 */
 299#define MK_PEXDADRS(bus_no, dev_no, func_no, addr) \
 300        ((uint32_t)(((addr) & ~0x3UL) | \
 301        ((bus_no) << PEXDADRS_BUSNO_SHIFT) | \
 302        ((dev_no)  << PEXDADRS_DEVNO_SHIFT) | \
 303        ((func_no) << PEXDADRS_FUNCNO_SHIFT)))
 304
 305#define MK_PEXDCMND_BYTE_EN(addr, size) \
 306        ((((0x1 << (size))-1) << ((addr) & 0x3)) << PEXDCMND_BYTE_EN_SHIFT)
 307#define MK_PEXDCMND(cmd, addr, size) ((cmd) | MK_PEXDCMND_BYTE_EN(addr, size))
 308
 309static uint32_t config_read_pciex_dev(unsigned int __iomem *base,
 310                uint64_t bus_no, uint64_t dev_no, uint64_t func_no,
 311                uint64_t off, uint64_t size)
 312{
 313        uint32_t ret;
 314        uint32_t addr, cmd;
 315
 316        addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
 317        cmd = MK_PEXDCMND(PEXDCMND_CONFIG_READ, off, size);
 318        PEX_OUT(base, PEXDADRS, addr);
 319        PEX_OUT(base, PEXDCMND, cmd);
 320        ret = (PEX_IN(base, PEXDRDATA)
 321                >> ((off & (4-size)) * 8)) & ((0x1 << (size * 8)) - 1);
 322        return ret;
 323}
 324
 325static void config_write_pciex_dev(unsigned int __iomem *base, uint64_t bus_no,
 326        uint64_t dev_no, uint64_t func_no, uint64_t off, uint64_t size,
 327        uint32_t data)
 328{
 329        uint32_t addr, cmd;
 330
 331        addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
 332        cmd = MK_PEXDCMND(PEXDCMND_CONFIG_WRITE, off, size);
 333        PEX_OUT(base, PEXDADRS, addr);
 334        PEX_OUT(base, PEXDCMND, cmd);
 335        PEX_OUT(base, PEXDWDATA,
 336                (data & ((0x1 << (size * 8)) - 1)) << ((off & (4-size)) * 8));
 337}
 338
 339#define MK_PEXCADRS_BYTE_EN(off, len) \
 340        ((((0x1 << (len)) - 1) << ((off) & 0x3)) << PEXCADRS_BYTE_EN_SHIFT)
 341#define MK_PEXCADRS(cmd, addr, size) \
 342        ((cmd) | MK_PEXCADRS_BYTE_EN(addr, size) | ((addr) & ~0x3))
 343static uint32_t config_read_pciex_rc(unsigned int __iomem *base,
 344                                     uint32_t where, uint32_t size)
 345{
 346        PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_READ, where, size));
 347        return (PEX_IN(base, PEXCRDATA)
 348                >> ((where & (4 - size)) * 8)) & ((0x1 << (size * 8)) - 1);
 349}
 350
 351static void config_write_pciex_rc(unsigned int __iomem *base, uint32_t where,
 352                                  uint32_t size, uint32_t val)
 353{
 354        uint32_t data;
 355
 356        data = (val & ((0x1 << (size * 8)) - 1)) << ((where & (4 - size)) * 8);
 357        PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_WRITE, where, size));
 358        PEX_OUT(base, PEXCWDATA, data);
 359}
 360
 361/* Interfaces */
 362/* Note: Work-around
 363 *  On SCC PCIEXC, one device is seen on all 32 dev_no.
 364 *  As SCC PCIEXC can have only one device on the bus, we look only one dev_no.
 365 * (dev_no = 1)
 366 */
 367static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
 368                                 int where, int size, unsigned int *val)
 369{
 370        struct pci_controller *phb = pci_bus_to_host(bus);
 371
 372        if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
 373                *val = ~0;
 374                return PCIBIOS_DEVICE_NOT_FOUND;
 375        }
 376
 377        if (bus->number == 0 && PCI_SLOT(devfn) == 0)
 378                *val = config_read_pciex_rc(phb->cfg_addr, where, size);
 379        else
 380                *val = config_read_pciex_dev(phb->cfg_addr, bus->number,
 381                                PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
 382
 383        return PCIBIOS_SUCCESSFUL;
 384}
 385
 386static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
 387                                  int where, int size, unsigned int val)
 388{
 389        struct pci_controller *phb = pci_bus_to_host(bus);
 390
 391        if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
 392                return PCIBIOS_DEVICE_NOT_FOUND;
 393
 394        if (bus->number == 0 && PCI_SLOT(devfn) == 0)
 395                config_write_pciex_rc(phb->cfg_addr, where, size, val);
 396        else
 397                config_write_pciex_dev(phb->cfg_addr, bus->number,
 398                        PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
 399        return PCIBIOS_SUCCESSFUL;
 400}
 401
 402static struct pci_ops scc_pciex_pci_ops = {
 403        scc_pciex_read_config,
 404        scc_pciex_write_config,
 405};
 406
 407static void pciex_clear_intr_all(unsigned int __iomem *base)
 408{
 409        PEX_OUT(base, PEXAERRSTS, 0xffffffff);
 410        PEX_OUT(base, PEXPRERRSTS, 0xffffffff);
 411        PEX_OUT(base, PEXINTSTS, 0xffffffff);
 412}
 413
 414#if 0
 415static void pciex_disable_intr_all(unsigned int *base)
 416{
 417        PEX_OUT(base, PEXINTMASK,   0x0);
 418        PEX_OUT(base, PEXAERRMASK,  0x0);
 419        PEX_OUT(base, PEXPRERRMASK, 0x0);
 420        PEX_OUT(base, PEXVDMASK,    0x0);
 421}
 422#endif
 423
 424static void pciex_enable_intr_all(unsigned int __iomem *base)
 425{
 426        PEX_OUT(base, PEXINTMASK, 0x0000e7f1);
 427        PEX_OUT(base, PEXAERRMASK, 0x03ff01ff);
 428        PEX_OUT(base, PEXPRERRMASK, 0x0001010f);
 429        PEX_OUT(base, PEXVDMASK, 0x00000001);
 430}
 431
 432static void pciex_check_status(unsigned int __iomem *base)
 433{
 434        uint32_t err = 0;
 435        uint32_t intsts, aerr, prerr, rcvcp, lenerr;
 436        uint32_t maea, maec;
 437
 438        intsts = PEX_IN(base, PEXINTSTS);
 439        aerr = PEX_IN(base, PEXAERRSTS);
 440        prerr = PEX_IN(base, PEXPRERRSTS);
 441        rcvcp = PEX_IN(base, PEXRCVCPLIDA);
 442        lenerr = PEX_IN(base, PEXLENERRIDA);
 443
 444        if (intsts || aerr || prerr || rcvcp || lenerr)
 445                err = 1;
 446
 447        pr_info("PCEXC interrupt!!\n");
 448        pr_info("PEXINTSTS    :0x%08x\n", intsts);
 449        pr_info("PEXAERRSTS   :0x%08x\n", aerr);
 450        pr_info("PEXPRERRSTS  :0x%08x\n", prerr);
 451        pr_info("PEXRCVCPLIDA :0x%08x\n", rcvcp);
 452        pr_info("PEXLENERRIDA :0x%08x\n", lenerr);
 453
 454        /* print detail of Protection Error */
 455        if (intsts & 0x00004000) {
 456                uint32_t i, n;
 457                for (i = 0; i < 4; i++) {
 458                        n = 1 << i;
 459                        if (prerr & n) {
 460                                maea = PEX_IN(base, PEXMAEA(i));
 461                                maec = PEX_IN(base, PEXMAEC(i));
 462                                pr_info("PEXMAEC%d     :0x%08x\n", i, maec);
 463                                pr_info("PEXMAEA%d     :0x%08x\n", i, maea);
 464                        }
 465                }
 466        }
 467
 468        if (err)
 469                pciex_clear_intr_all(base);
 470}
 471
 472static irqreturn_t pciex_handle_internal_irq(int irq, void *dev_id)
 473{
 474        struct pci_controller *phb = dev_id;
 475
 476        pr_debug("PCIEX:pciex_handle_internal_irq(irq=%d)\n", irq);
 477
 478        BUG_ON(phb->cfg_addr == NULL);
 479
 480        pciex_check_status(phb->cfg_addr);
 481
 482        return IRQ_HANDLED;
 483}
 484
 485static __init int celleb_setup_pciex(struct device_node *node,
 486                                     struct pci_controller *phb)
 487{
 488        struct resource r;
 489        struct of_irq oirq;
 490        int virq;
 491
 492        /* SMMIO registers; used inside this file */
 493        if (of_address_to_resource(node, 0, &r)) {
 494                pr_err("PCIEXC:Failed to get config resource.\n");
 495                return 1;
 496        }
 497        phb->cfg_addr = ioremap(r.start, resource_size(&r));
 498        if (!phb->cfg_addr) {
 499                pr_err("PCIEXC:Failed to remap SMMIO region.\n");
 500                return 1;
 501        }
 502
 503        /* Not use cfg_data,  cmd and data regs are near address reg */
 504        phb->cfg_data = NULL;
 505
 506        /* set pci_ops */
 507        phb->ops = &scc_pciex_pci_ops;
 508
 509        /* internal interrupt handler */
 510        if (of_irq_map_one(node, 1, &oirq)) {
 511                pr_err("PCIEXC:Failed to map irq\n");
 512                goto error;
 513        }
 514        virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
 515                                     oirq.size);
 516        if (request_irq(virq, pciex_handle_internal_irq,
 517                        0, "pciex", (void *)phb)) {
 518                pr_err("PCIEXC:Failed to request irq\n");
 519                goto error;
 520        }
 521
 522        /* enable all interrupts */
 523        pciex_clear_intr_all(phb->cfg_addr);
 524        pciex_enable_intr_all(phb->cfg_addr);
 525        /* MSI: TBD */
 526
 527        return 0;
 528
 529error:
 530        phb->cfg_data = NULL;
 531        if (phb->cfg_addr)
 532                iounmap(phb->cfg_addr);
 533        phb->cfg_addr = NULL;
 534        return 1;
 535}
 536
 537struct celleb_phb_spec celleb_pciex_spec __initdata = {
 538        .setup = celleb_setup_pciex,
 539        .ops = &scc_pciex_ops,
 540        .iowa_init = &scc_pciex_iowa_init,
 541};
 542