linux/arch/mips/pci/pci-ar724x.c
<<
>>
Prefs
   1/*
   2 *  Atheros AR724X PCI host controller driver
   3 *
   4 *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
   5 *  Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
   6 *
   7 *  This program is free software; you can redistribute it and/or modify it
   8 *  under the terms of the GNU General Public License version 2 as published
   9 *  by the Free Software Foundation.
  10 */
  11
  12#include <linux/spinlock.h>
  13#include <linux/irq.h>
  14#include <linux/pci.h>
  15#include <linux/module.h>
  16#include <linux/platform_device.h>
  17#include <asm/mach-ath79/ath79.h>
  18#include <asm/mach-ath79/ar71xx_regs.h>
  19
  20#define AR724X_PCI_REG_RESET            0x18
  21#define AR724X_PCI_REG_INT_STATUS       0x4c
  22#define AR724X_PCI_REG_INT_MASK         0x50
  23
  24#define AR724X_PCI_RESET_LINK_UP        BIT(0)
  25
  26#define AR724X_PCI_INT_DEV0             BIT(14)
  27
  28#define AR724X_PCI_IRQ_COUNT            1
  29
  30#define AR7240_BAR0_WAR_VALUE   0xffff
  31
  32#define AR724X_PCI_CMD_INIT     (PCI_COMMAND_MEMORY |           \
  33                                 PCI_COMMAND_MASTER |           \
  34                                 PCI_COMMAND_INVALIDATE |       \
  35                                 PCI_COMMAND_PARITY |           \
  36                                 PCI_COMMAND_SERR |             \
  37                                 PCI_COMMAND_FAST_BACK)
  38
  39struct ar724x_pci_controller {
  40        void __iomem *devcfg_base;
  41        void __iomem *ctrl_base;
  42        void __iomem *crp_base;
  43
  44        int irq;
  45        int irq_base;
  46
  47        bool link_up;
  48        bool bar0_is_cached;
  49        u32  bar0_value;
  50
  51        spinlock_t lock;
  52
  53        struct pci_controller pci_controller;
  54        struct resource io_res;
  55        struct resource mem_res;
  56};
  57
  58static inline bool ar724x_pci_check_link(struct ar724x_pci_controller *apc)
  59{
  60        u32 reset;
  61
  62        reset = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
  63        return reset & AR724X_PCI_RESET_LINK_UP;
  64}
  65
  66static inline struct ar724x_pci_controller *
  67pci_bus_to_ar724x_controller(struct pci_bus *bus)
  68{
  69        struct pci_controller *hose;
  70
  71        hose = (struct pci_controller *) bus->sysdata;
  72        return container_of(hose, struct ar724x_pci_controller, pci_controller);
  73}
  74
  75static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
  76                                  int where, int size, u32 value)
  77{
  78        unsigned long flags;
  79        void __iomem *base;
  80        u32 data;
  81        int s;
  82
  83        WARN_ON(where & (size - 1));
  84
  85        if (!apc->link_up)
  86                return PCIBIOS_DEVICE_NOT_FOUND;
  87
  88        base = apc->crp_base;
  89
  90        spin_lock_irqsave(&apc->lock, flags);
  91        data = __raw_readl(base + (where & ~3));
  92
  93        switch (size) {
  94        case 1:
  95                s = ((where & 3) * 8);
  96                data &= ~(0xff << s);
  97                data |= ((value & 0xff) << s);
  98                break;
  99        case 2:
 100                s = ((where & 2) * 8);
 101                data &= ~(0xffff << s);
 102                data |= ((value & 0xffff) << s);
 103                break;
 104        case 4:
 105                data = value;
 106                break;
 107        default:
 108                spin_unlock_irqrestore(&apc->lock, flags);
 109                return PCIBIOS_BAD_REGISTER_NUMBER;
 110        }
 111
 112        __raw_writel(data, base + (where & ~3));
 113        /* flush write */
 114        __raw_readl(base + (where & ~3));
 115        spin_unlock_irqrestore(&apc->lock, flags);
 116
 117        return PCIBIOS_SUCCESSFUL;
 118}
 119
 120static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
 121                            int size, uint32_t *value)
 122{
 123        struct ar724x_pci_controller *apc;
 124        unsigned long flags;
 125        void __iomem *base;
 126        u32 data;
 127
 128        apc = pci_bus_to_ar724x_controller(bus);
 129        if (!apc->link_up)
 130                return PCIBIOS_DEVICE_NOT_FOUND;
 131
 132        if (devfn)
 133                return PCIBIOS_DEVICE_NOT_FOUND;
 134
 135        base = apc->devcfg_base;
 136
 137        spin_lock_irqsave(&apc->lock, flags);
 138        data = __raw_readl(base + (where & ~3));
 139
 140        switch (size) {
 141        case 1:
 142                if (where & 1)
 143                        data >>= 8;
 144                if (where & 2)
 145                        data >>= 16;
 146                data &= 0xff;
 147                break;
 148        case 2:
 149                if (where & 2)
 150                        data >>= 16;
 151                data &= 0xffff;
 152                break;
 153        case 4:
 154                break;
 155        default:
 156                spin_unlock_irqrestore(&apc->lock, flags);
 157
 158                return PCIBIOS_BAD_REGISTER_NUMBER;
 159        }
 160
 161        spin_unlock_irqrestore(&apc->lock, flags);
 162
 163        if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
 164            apc->bar0_is_cached) {
 165                /* use the cached value */
 166                *value = apc->bar0_value;
 167        } else {
 168                *value = data;
 169        }
 170
 171        return PCIBIOS_SUCCESSFUL;
 172}
 173
 174static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
 175                             int size, uint32_t value)
 176{
 177        struct ar724x_pci_controller *apc;
 178        unsigned long flags;
 179        void __iomem *base;
 180        u32 data;
 181        int s;
 182
 183        apc = pci_bus_to_ar724x_controller(bus);
 184        if (!apc->link_up)
 185                return PCIBIOS_DEVICE_NOT_FOUND;
 186
 187        if (devfn)
 188                return PCIBIOS_DEVICE_NOT_FOUND;
 189
 190        if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
 191                if (value != 0xffffffff) {
 192                        /*
 193                         * WAR for a hw issue. If the BAR0 register of the
 194                         * device is set to the proper base address, the
 195                         * memory space of the device is not accessible.
 196                         *
 197                         * Cache the intended value so it can be read back,
 198                         * and write a SoC specific constant value to the
 199                         * BAR0 register in order to make the device memory
 200                         * accessible.
 201                         */
 202                        apc->bar0_is_cached = true;
 203                        apc->bar0_value = value;
 204
 205                        value = AR7240_BAR0_WAR_VALUE;
 206                } else {
 207                        apc->bar0_is_cached = false;
 208                }
 209        }
 210
 211        base = apc->devcfg_base;
 212
 213        spin_lock_irqsave(&apc->lock, flags);
 214        data = __raw_readl(base + (where & ~3));
 215
 216        switch (size) {
 217        case 1:
 218                s = ((where & 3) * 8);
 219                data &= ~(0xff << s);
 220                data |= ((value & 0xff) << s);
 221                break;
 222        case 2:
 223                s = ((where & 2) * 8);
 224                data &= ~(0xffff << s);
 225                data |= ((value & 0xffff) << s);
 226                break;
 227        case 4:
 228                data = value;
 229                break;
 230        default:
 231                spin_unlock_irqrestore(&apc->lock, flags);
 232
 233                return PCIBIOS_BAD_REGISTER_NUMBER;
 234        }
 235
 236        __raw_writel(data, base + (where & ~3));
 237        /* flush write */
 238        __raw_readl(base + (where & ~3));
 239        spin_unlock_irqrestore(&apc->lock, flags);
 240
 241        return PCIBIOS_SUCCESSFUL;
 242}
 243
 244static struct pci_ops ar724x_pci_ops = {
 245        .read   = ar724x_pci_read,
 246        .write  = ar724x_pci_write,
 247};
 248
 249static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
 250{
 251        struct ar724x_pci_controller *apc;
 252        void __iomem *base;
 253        u32 pending;
 254
 255        apc = irq_get_handler_data(irq);
 256        base = apc->ctrl_base;
 257
 258        pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
 259                  __raw_readl(base + AR724X_PCI_REG_INT_MASK);
 260
 261        if (pending & AR724X_PCI_INT_DEV0)
 262                generic_handle_irq(apc->irq_base + 0);
 263
 264        else
 265                spurious_interrupt();
 266}
 267
 268static void ar724x_pci_irq_unmask(struct irq_data *d)
 269{
 270        struct ar724x_pci_controller *apc;
 271        void __iomem *base;
 272        int offset;
 273        u32 t;
 274
 275        apc = irq_data_get_irq_chip_data(d);
 276        base = apc->ctrl_base;
 277        offset = apc->irq_base - d->irq;
 278
 279        switch (offset) {
 280        case 0:
 281                t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
 282                __raw_writel(t | AR724X_PCI_INT_DEV0,
 283                             base + AR724X_PCI_REG_INT_MASK);
 284                /* flush write */
 285                __raw_readl(base + AR724X_PCI_REG_INT_MASK);
 286        }
 287}
 288
 289static void ar724x_pci_irq_mask(struct irq_data *d)
 290{
 291        struct ar724x_pci_controller *apc;
 292        void __iomem *base;
 293        int offset;
 294        u32 t;
 295
 296        apc = irq_data_get_irq_chip_data(d);
 297        base = apc->ctrl_base;
 298        offset = apc->irq_base - d->irq;
 299
 300        switch (offset) {
 301        case 0:
 302                t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
 303                __raw_writel(t & ~AR724X_PCI_INT_DEV0,
 304                             base + AR724X_PCI_REG_INT_MASK);
 305
 306                /* flush write */
 307                __raw_readl(base + AR724X_PCI_REG_INT_MASK);
 308
 309                t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
 310                __raw_writel(t | AR724X_PCI_INT_DEV0,
 311                             base + AR724X_PCI_REG_INT_STATUS);
 312
 313                /* flush write */
 314                __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
 315        }
 316}
 317
 318static struct irq_chip ar724x_pci_irq_chip = {
 319        .name           = "AR724X PCI ",
 320        .irq_mask       = ar724x_pci_irq_mask,
 321        .irq_unmask     = ar724x_pci_irq_unmask,
 322        .irq_mask_ack   = ar724x_pci_irq_mask,
 323};
 324
 325static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc,
 326                                int id)
 327{
 328        void __iomem *base;
 329        int i;
 330
 331        base = apc->ctrl_base;
 332
 333        __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
 334        __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
 335
 336        apc->irq_base = ATH79_PCI_IRQ_BASE + (id * AR724X_PCI_IRQ_COUNT);
 337
 338        for (i = apc->irq_base;
 339             i < apc->irq_base + AR724X_PCI_IRQ_COUNT; i++) {
 340                irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
 341                                         handle_level_irq);
 342                irq_set_chip_data(i, apc);
 343        }
 344
 345        irq_set_handler_data(apc->irq, apc);
 346        irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
 347}
 348
 349static int ar724x_pci_probe(struct platform_device *pdev)
 350{
 351        struct ar724x_pci_controller *apc;
 352        struct resource *res;
 353        int id;
 354
 355        id = pdev->id;
 356        if (id == -1)
 357                id = 0;
 358
 359        apc = devm_kzalloc(&pdev->dev, sizeof(struct ar724x_pci_controller),
 360                            GFP_KERNEL);
 361        if (!apc)
 362                return -ENOMEM;
 363
 364        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl_base");
 365        if (!res)
 366                return -EINVAL;
 367
 368        apc->ctrl_base = devm_ioremap_resource(&pdev->dev, res);
 369        if (IS_ERR(apc->ctrl_base))
 370                return PTR_ERR(apc->ctrl_base);
 371
 372        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
 373        if (!res)
 374                return -EINVAL;
 375
 376        apc->devcfg_base = devm_ioremap_resource(&pdev->dev, res);
 377        if (IS_ERR(apc->devcfg_base))
 378                return PTR_ERR(apc->devcfg_base);
 379
 380        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crp_base");
 381        if (!res)
 382                return -EINVAL;
 383
 384        apc->crp_base = devm_ioremap_resource(&pdev->dev, res);
 385        if (IS_ERR(apc->crp_base))
 386                return PTR_ERR(apc->crp_base);
 387
 388        apc->irq = platform_get_irq(pdev, 0);
 389        if (apc->irq < 0)
 390                return -EINVAL;
 391
 392        spin_lock_init(&apc->lock);
 393
 394        res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
 395        if (!res)
 396                return -EINVAL;
 397
 398        apc->io_res.parent = res;
 399        apc->io_res.name = "PCI IO space";
 400        apc->io_res.start = res->start;
 401        apc->io_res.end = res->end;
 402        apc->io_res.flags = IORESOURCE_IO;
 403
 404        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem_base");
 405        if (!res)
 406                return -EINVAL;
 407
 408        apc->mem_res.parent = res;
 409        apc->mem_res.name = "PCI memory space";
 410        apc->mem_res.start = res->start;
 411        apc->mem_res.end = res->end;
 412        apc->mem_res.flags = IORESOURCE_MEM;
 413
 414        apc->pci_controller.pci_ops = &ar724x_pci_ops;
 415        apc->pci_controller.io_resource = &apc->io_res;
 416        apc->pci_controller.mem_resource = &apc->mem_res;
 417
 418        apc->link_up = ar724x_pci_check_link(apc);
 419        if (!apc->link_up)
 420                dev_warn(&pdev->dev, "PCIe link is down\n");
 421
 422        ar724x_pci_irq_init(apc, id);
 423
 424        ar724x_pci_local_write(apc, PCI_COMMAND, 4, AR724X_PCI_CMD_INIT);
 425
 426        register_pci_controller(&apc->pci_controller);
 427
 428        return 0;
 429}
 430
 431static struct platform_driver ar724x_pci_driver = {
 432        .probe = ar724x_pci_probe,
 433        .driver = {
 434                .name = "ar724x-pci",
 435                .owner = THIS_MODULE,
 436        },
 437};
 438
 439static int __init ar724x_pci_init(void)
 440{
 441        return platform_driver_register(&ar724x_pci_driver);
 442}
 443
 444postcore_initcall(ar724x_pci_init);
 445