ARM: mvebu: Staticize mvebu_cpu_reset_init
[deliverable/linux.git] / arch / arm / mach-kirkwood / pcie.c
CommitLineData
651c74c7
SB
1/*
2 * arch/arm/mach-kirkwood/pcie.c
3 *
4 * PCIe functions for Marvell Kirkwood SoCs
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/pci.h>
5a0e3ad6 13#include <linux/slab.h>
27e53cfb 14#include <linux/clk.h>
5afb9fe3 15#include <linux/mbus.h>
cc22b4c1 16#include <video/vga.h>
6e5c11a1 17#include <asm/irq.h>
651c74c7 18#include <asm/mach/pci.h>
6f088f1d 19#include <plat/pcie.h>
e8b2b7ba 20#include <mach/bridge-regs.h>
651c74c7
SB
21#include "common.h"
22
8baeeeb2
TP
23/* These can go away once Kirkwood uses the mvebu-mbus DT binding */
24#define KIRKWOOD_MBUS_PCIE0_MEM_TARGET 0x4
25#define KIRKWOOD_MBUS_PCIE0_MEM_ATTR 0xe8
26#define KIRKWOOD_MBUS_PCIE0_IO_TARGET 0x4
27#define KIRKWOOD_MBUS_PCIE0_IO_ATTR 0xe0
28#define KIRKWOOD_MBUS_PCIE1_MEM_TARGET 0x4
29#define KIRKWOOD_MBUS_PCIE1_MEM_ATTR 0xd8
30#define KIRKWOOD_MBUS_PCIE1_IO_TARGET 0x4
31#define KIRKWOOD_MBUS_PCIE1_IO_ATTR 0xd0
32
27e53cfb
AL
33static void kirkwood_enable_pcie_clk(const char *port)
34{
35 struct clk *clk;
36
37 clk = clk_get_sys("pcie", port);
38 if (IS_ERR(clk)) {
98adf932 39 pr_err("PCIE clock %s missing\n", port);
27e53cfb
AL
40 return;
41 }
42 clk_prepare_enable(clk);
43 clk_put(clk);
44}
45
46/* This function is called very early in the boot when probing the
47 hardware to determine what we actually are, and what rate tclk is
48 ticking at. Hence calling kirkwood_enable_pcie_clk() is not
49 possible since the clk tree has not been created yet. */
0e0cdd37
EC
50void kirkwood_enable_pcie(void)
51{
52 u32 curr = readl(CLOCK_GATING_CTRL);
53 if (!(curr & CGC_PEX0))
54 writel(curr | CGC_PEX0, CLOCK_GATING_CTRL);
55}
56
98d9986c 57void kirkwood_pcie_id(u32 *dev, u32 *rev)
ffd58bd2 58{
0e0cdd37 59 kirkwood_enable_pcie();
060f3d19
TP
60 *dev = orion_pcie_dev_id(PCIE_VIRT_BASE);
61 *rev = orion_pcie_rev(PCIE_VIRT_BASE);
ffd58bd2 62}
651c74c7 63
ffd58bd2
SB
64struct pcie_port {
65 u8 root_bus_nr;
66 void __iomem *base;
67 spinlock_t conf_lock;
68 int irq;
2bb08085 69 struct resource res;
ffd58bd2 70};
651c74c7 71
ffd58bd2
SB
72static int pcie_port_map[2];
73static int num_pcie_ports;
74
ffd58bd2 75static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
651c74c7
SB
76{
77 /*
78 * Don't go out when trying to access --
79 * 1. nonexisting device on local bus
80 * 2. where there's no device connected (no link)
81 */
ffd58bd2 82 if (bus == pp->root_bus_nr && dev == 0)
651c74c7
SB
83 return 1;
84
ffd58bd2 85 if (!orion_pcie_link_up(pp->base))
651c74c7
SB
86 return 0;
87
ffd58bd2 88 if (bus == pp->root_bus_nr && dev != 1)
651c74c7
SB
89 return 0;
90
91 return 1;
92}
93
94
95/*
96 * PCIe config cycles are done by programming the PCIE_CONF_ADDR register
97 * and then reading the PCIE_CONF_DATA register. Need to make sure these
98 * transactions are atomic.
99 */
651c74c7
SB
100
101static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
102 int size, u32 *val)
103{
43ba990b
RK
104 struct pci_sys_data *sys = bus->sysdata;
105 struct pcie_port *pp = sys->private_data;
651c74c7
SB
106 unsigned long flags;
107 int ret;
108
ffd58bd2 109 if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
651c74c7
SB
110 *val = 0xffffffff;
111 return PCIBIOS_DEVICE_NOT_FOUND;
112 }
113
ffd58bd2
SB
114 spin_lock_irqsave(&pp->conf_lock, flags);
115 ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
116 spin_unlock_irqrestore(&pp->conf_lock, flags);
651c74c7
SB
117
118 return ret;
119}
120
121static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
122 int where, int size, u32 val)
123{
43ba990b
RK
124 struct pci_sys_data *sys = bus->sysdata;
125 struct pcie_port *pp = sys->private_data;
651c74c7
SB
126 unsigned long flags;
127 int ret;
128
ffd58bd2 129 if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
651c74c7
SB
130 return PCIBIOS_DEVICE_NOT_FOUND;
131
ffd58bd2
SB
132 spin_lock_irqsave(&pp->conf_lock, flags);
133 ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
134 spin_unlock_irqrestore(&pp->conf_lock, flags);
651c74c7
SB
135
136 return ret;
137}
138
139static struct pci_ops pcie_ops = {
140 .read = pcie_rd_conf,
141 .write = pcie_wr_conf,
142};
143
a87182b3 144static void __init pcie0_ioresources_init(struct pcie_port *pp)
651c74c7 145{
060f3d19 146 pp->base = PCIE_VIRT_BASE;
a87182b3 147 pp->irq = IRQ_KIRKWOOD_PCIE;
651c74c7 148
651c74c7 149 /*
ffd58bd2 150 * IORESOURCE_MEM
651c74c7 151 */
2bb08085
RH
152 pp->res.name = "PCIe 0 MEM";
153 pp->res.start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
154 pp->res.end = pp->res.start + KIRKWOOD_PCIE_MEM_SIZE - 1;
155 pp->res.flags = IORESOURCE_MEM;
ffd58bd2
SB
156}
157
a87182b3 158static void __init pcie1_ioresources_init(struct pcie_port *pp)
ffd58bd2 159{
060f3d19 160 pp->base = PCIE1_VIRT_BASE;
a87182b3 161 pp->irq = IRQ_KIRKWOOD_PCIE1;
651c74c7 162
651c74c7
SB
163 /*
164 * IORESOURCE_MEM
165 */
2bb08085
RH
166 pp->res.name = "PCIe 1 MEM";
167 pp->res.start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
168 pp->res.end = pp->res.start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
169 pp->res.flags = IORESOURCE_MEM;
ffd58bd2
SB
170}
171
172static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
173{
ffd58bd2
SB
174 struct pcie_port *pp;
175 int index;
176
177 if (nr >= num_pcie_ports)
178 return 0;
179
180 index = pcie_port_map[nr];
98adf932 181 pr_info("PCI: bus%d uses PCIe port %d\n", sys->busnr, index);
ffd58bd2
SB
182
183 pp = kzalloc(sizeof(*pp), GFP_KERNEL);
184 if (!pp)
185 panic("PCIe: failed to allocate pcie_port data");
186 sys->private_data = pp;
187 pp->root_bus_nr = sys->busnr;
188 spin_lock_init(&pp->conf_lock);
189
190 switch (index) {
191 case 0:
27e53cfb 192 kirkwood_enable_pcie_clk("0");
a87182b3 193 pcie0_ioresources_init(pp);
2bb08085 194 pci_ioremap_io(SZ_64K * sys->busnr, KIRKWOOD_PCIE_IO_PHYS_BASE);
ffd58bd2
SB
195 break;
196 case 1:
27e53cfb 197 kirkwood_enable_pcie_clk("1");
a87182b3 198 pcie1_ioresources_init(pp);
98adf932
AL
199 pci_ioremap_io(SZ_64K * sys->busnr,
200 KIRKWOOD_PCIE1_IO_PHYS_BASE);
ffd58bd2
SB
201 break;
202 default:
a87182b3 203 panic("PCIe setup: invalid controller %d", index);
ffd58bd2
SB
204 }
205
2bb08085 206 if (request_resource(&iomem_resource, &pp->res))
a87182b3
NP
207 panic("Request PCIe%d Memory resource failed\n", index);
208
2bb08085 209 pci_add_resource_offset(&sys->resources, &pp->res, sys->mem_offset);
a87182b3 210
ffd58bd2
SB
211 /*
212 * Generic PCIe unit setup.
213 */
214 orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
215
63a9332b 216 orion_pcie_setup(pp->base);
e8b2b7ba 217
651c74c7
SB
218 return 1;
219}
220
1dc831bf
JG
221/*
222 * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
223 * is operating as a root complex this needs to be switched to
224 * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
225 * the device. Decoding setup is handled by the orion code.
226 */
351a102d 227static void rc_pci_fixup(struct pci_dev *dev)
651c74c7 228{
651c74c7
SB
229 if (dev->bus->parent == NULL && dev->devfn == 0) {
230 int i;
231
1dc831bf
JG
232 dev->class &= 0xff;
233 dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
651c74c7
SB
234 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
235 dev->resource[i].start = 0;
236 dev->resource[i].end = 0;
237 dev->resource[i].flags = 0;
238 }
239 }
240}
241DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
242
d5341942
RB
243static int __init kirkwood_pcie_map_irq(const struct pci_dev *dev, u8 slot,
244 u8 pin)
651c74c7 245{
43ba990b
RK
246 struct pci_sys_data *sys = dev->sysdata;
247 struct pcie_port *pp = sys->private_data;
ffd58bd2
SB
248
249 return pp->irq;
651c74c7
SB
250}
251
252static struct hw_pci kirkwood_pci __initdata = {
651c74c7 253 .setup = kirkwood_pcie_setup,
651c74c7 254 .map_irq = kirkwood_pcie_map_irq,
4a9329a0 255 .ops = &pcie_ops,
651c74c7
SB
256};
257
060f3d19 258static void __init add_pcie_port(int index, void __iomem *base)
ffd58bd2 259{
b73690c8
JG
260 pcie_port_map[num_pcie_ports++] = index;
261 pr_info("Kirkwood PCIe port %d: link %s\n", index,
262 orion_pcie_link_up(base) ? "up" : "down");
ffd58bd2
SB
263}
264
265void __init kirkwood_pcie_init(unsigned int portmask)
651c74c7 266{
8baeeeb2
TP
267 mvebu_mbus_add_window_remap_by_id(KIRKWOOD_MBUS_PCIE0_IO_TARGET,
268 KIRKWOOD_MBUS_PCIE0_IO_ATTR,
5afb9fe3
TP
269 KIRKWOOD_PCIE_IO_PHYS_BASE,
270 KIRKWOOD_PCIE_IO_SIZE,
8baeeeb2
TP
271 KIRKWOOD_PCIE_IO_BUS_BASE);
272 mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_PCIE0_MEM_TARGET,
273 KIRKWOOD_MBUS_PCIE0_MEM_ATTR,
274 KIRKWOOD_PCIE_MEM_PHYS_BASE,
275 KIRKWOOD_PCIE_MEM_SIZE);
276 mvebu_mbus_add_window_remap_by_id(KIRKWOOD_MBUS_PCIE1_IO_TARGET,
277 KIRKWOOD_MBUS_PCIE1_IO_ATTR,
5afb9fe3
TP
278 KIRKWOOD_PCIE1_IO_PHYS_BASE,
279 KIRKWOOD_PCIE1_IO_SIZE,
8baeeeb2
TP
280 KIRKWOOD_PCIE1_IO_BUS_BASE);
281 mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_PCIE1_MEM_TARGET,
282 KIRKWOOD_MBUS_PCIE1_MEM_ATTR,
283 KIRKWOOD_PCIE1_MEM_PHYS_BASE,
284 KIRKWOOD_PCIE1_MEM_SIZE);
5afb9fe3 285
cc22b4c1
RH
286 vga_base = KIRKWOOD_PCIE_MEM_PHYS_BASE;
287
ffd58bd2
SB
288 if (portmask & KW_PCIE0)
289 add_pcie_port(0, PCIE_VIRT_BASE);
290
291 if (portmask & KW_PCIE1)
292 add_pcie_port(1, PCIE1_VIRT_BASE);
293
294 kirkwood_pci.nr_controllers = num_pcie_ports;
651c74c7
SB
295 pci_common_init(&kirkwood_pci);
296}
This page took 0.332072 seconds and 5 git commands to generate.