2 * Atheros 724x PCI support
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
11 #include <linux/pci.h>
12 #include <asm/mach-ath79/pci.h>
14 #define AR724X_PCI_CFG_BASE 0x14000000
15 #define AR724X_PCI_CFG_SIZE 0x1000
16 #define AR724X_PCI_MEM_BASE 0x10000000
17 #define AR724X_PCI_MEM_SIZE 0x08000000
19 static DEFINE_SPINLOCK(ar724x_pci_lock);
20 static void __iomem *ar724x_pci_devcfg_base;
22 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
23 int size, uint32_t *value)
30 return PCIBIOS_DEVICE_NOT_FOUND;
32 base = ar724x_pci_devcfg_base;
34 spin_lock_irqsave(&ar724x_pci_lock, flags);
35 data = __raw_readl(base + (where & ~3));
53 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
55 return PCIBIOS_BAD_REGISTER_NUMBER;
58 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
61 return PCIBIOS_SUCCESSFUL;
64 static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
65 int size, uint32_t value)
73 return PCIBIOS_DEVICE_NOT_FOUND;
75 base = ar724x_pci_devcfg_base;
77 spin_lock_irqsave(&ar724x_pci_lock, flags);
78 data = __raw_readl(base + (where & ~3));
82 s = ((where & 3) * 8);
84 data |= ((value & 0xff) << s);
87 s = ((where & 2) * 8);
88 data &= ~(0xffff << s);
89 data |= ((value & 0xffff) << s);
95 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
97 return PCIBIOS_BAD_REGISTER_NUMBER;
100 __raw_writel(data, base + (where & ~3));
102 __raw_readl(base + (where & ~3));
103 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
105 return PCIBIOS_SUCCESSFUL;
108 static struct pci_ops ar724x_pci_ops = {
109 .read = ar724x_pci_read,
110 .write = ar724x_pci_write,
113 static struct resource ar724x_io_resource = {
114 .name = "PCI IO space",
117 .flags = IORESOURCE_IO,
120 static struct resource ar724x_mem_resource = {
121 .name = "PCI memory space",
122 .start = AR724X_PCI_MEM_BASE,
123 .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1,
124 .flags = IORESOURCE_MEM,
127 static struct pci_controller ar724x_pci_controller = {
128 .pci_ops = &ar724x_pci_ops,
129 .io_resource = &ar724x_io_resource,
130 .mem_resource = &ar724x_mem_resource,
133 int __init ar724x_pcibios_init(void)
135 ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
136 AR724X_PCI_CFG_SIZE);
137 if (ar724x_pci_devcfg_base == NULL)
140 register_pci_controller(&ar724x_pci_controller);
142 return PCIBIOS_SUCCESSFUL;