blob: 3271177239b99abd794a35fce8a074145d038bee [file] [log] [blame]
Jon Loeligerb809b3e2006-06-17 17:52:48 -05001/*
John Rigby5b70a092008-10-07 13:00:18 -06002 * MPC83xx/85xx/86xx PCI/PCIE support routing.
Jon Loeligerb809b3e2006-06-17 17:52:48 -05003 *
Scott Wood07e4f802012-07-10 19:26:47 -05004 * Copyright 2007-2012 Freescale Semiconductor, Inc.
Anton Vorontsov598804c2009-01-09 00:55:39 +03005 * Copyright 2008-2009 MontaVista Software, Inc.
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +08006 *
Jon Loeligerb809b3e2006-06-17 17:52:48 -05007 * Initial author: Xianghua Xiao <x.xiao@freescale.com>
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +08008 * Recode: ZHANG WEI <wei.zhang@freescale.com>
9 * Rewrite the routing for Frescale PCI and PCI Express
10 * Roy Zang <tie-fei.zang@freescale.com>
Anton Vorontsov598804c2009-01-09 00:55:39 +030011 * MPC83xx PCI-Express support:
12 * Tony Li <tony.li@freescale.com>
13 * Anton Vorontsov <avorontsov@ru.mvista.com>
Jon Loeligerb809b3e2006-06-17 17:52:48 -050014 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +080020#include <linux/kernel.h>
Jon Loeligerb809b3e2006-06-17 17:52:48 -050021#include <linux/pci.h>
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +080022#include <linux/delay.h>
23#include <linux/string.h>
24#include <linux/init.h>
25#include <linux/bootmem.h>
Yinghai Lu95f72d12010-07-12 14:36:09 +100026#include <linux/memblock.h>
Kumar Gala54c18192009-05-08 15:05:23 -050027#include <linux/log2.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090028#include <linux/slab.h>
Jon Loeligerb809b3e2006-06-17 17:52:48 -050029
Jon Loeligerb809b3e2006-06-17 17:52:48 -050030#include <asm/io.h>
31#include <asm/prom.h>
Jon Loeligerb809b3e2006-06-17 17:52:48 -050032#include <asm/pci-bridge.h>
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +080033#include <asm/machdep.h>
Jon Loeligerb809b3e2006-06-17 17:52:48 -050034#include <sysdev/fsl_soc.h>
Roy Zang55c44992007-07-10 18:44:34 +080035#include <sysdev/fsl_pci.h>
Jon Loeligerb809b3e2006-06-17 17:52:48 -050036
Kumar Galab8f44ec2010-08-05 02:45:08 -050037static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
Anton Vorontsov598804c2009-01-09 00:55:39 +030038
Greg Kroah-Hartmancad5cef2012-12-21 14:04:10 -080039static void quirk_fsl_pcie_header(struct pci_dev *dev)
Anton Vorontsov598804c2009-01-09 00:55:39 +030040{
Minghuan Lian59c58c32012-09-24 13:50:52 +080041 u8 hdr_type;
Kumar Gala470788d2011-05-19 19:56:50 -050042
Anton Vorontsov598804c2009-01-09 00:55:39 +030043 /* if we aren't a PCIe don't bother */
44 if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
45 return;
46
Kumar Gala470788d2011-05-19 19:56:50 -050047 /* if we aren't in host mode don't bother */
Minghuan Lian59c58c32012-09-24 13:50:52 +080048 pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
49 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
Kumar Gala470788d2011-05-19 19:56:50 -050050 return;
51
Anton Vorontsov598804c2009-01-09 00:55:39 +030052 dev->class = PCI_CLASS_BRIDGE_PCI << 8;
53 fsl_pcie_bus_fixup = 1;
54 return;
55}
56
Roy ZANGcc6ea0d2012-09-21 04:12:52 +000057static int __init fsl_pcie_check_link(struct pci_controller *hose,
58 struct resource *rsrc)
Anton Vorontsov598804c2009-01-09 00:55:39 +030059{
Roy ZANGcc6ea0d2012-09-21 04:12:52 +000060 struct ccsr_pci __iomem *pci = NULL;
Anton Vorontsov598804c2009-01-09 00:55:39 +030061 u32 val;
62
Roy ZANGcc6ea0d2012-09-21 04:12:52 +000063 /* for PCIe IP rev 3.0 or greater use CSR0 for link state */
64 if (rsrc) {
65 pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
66 (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
67 pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
68 if (!pci) {
69 dev_err(hose->parent, "Unable to map PCIe registers\n");
70 return -ENOMEM;
71 }
72 if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_3_0) {
73 val = (in_be32(&pci->pex_csr0) & PEX_CSR0_LTSSM_MASK)
74 >> PEX_CSR0_LTSSM_SHIFT;
75 if (val != PEX_CSR0_LTSSM_L0)
76 return 1;
77 iounmap(pci);
78 return 0;
79 }
80 iounmap(pci);
81 }
Anton Vorontsov598804c2009-01-09 00:55:39 +030082 early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
83 if (val < PCIE_LTSSM_L0)
84 return 1;
Roy ZANGcc6ea0d2012-09-21 04:12:52 +000085
Anton Vorontsov598804c2009-01-09 00:55:39 +030086 return 0;
87}
88
Kumar Gala5753c082009-10-16 18:31:48 -050089#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
Kumar Gala96ea3b42011-11-30 23:38:18 -060090
91#define MAX_PHYS_ADDR_BITS 40
92static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
93
94static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
95{
96 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
97 return -EIO;
98
99 /*
100 * Fixup PCI devices that are able to DMA to above the physical
101 * address width of the SoC such that we can address any internal
102 * SoC address from across PCI if needed
103 */
104 if ((dev->bus == &pci_bus_type) &&
105 dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
106 set_dma_ops(dev, &dma_direct_ops);
107 set_dma_offset(dev, pci64_dma_offset);
108 }
109
110 *dev->dma_mask = dma_mask;
111 return 0;
112}
113
Jia Hongtaoa393d892012-11-08 10:11:07 +0800114static int setup_one_atmu(struct ccsr_pci __iomem *pci,
Trent Piephoa097a782009-01-06 22:37:53 -0600115 unsigned int index, const struct resource *res,
116 resource_size_t offset)
117{
118 resource_size_t pci_addr = res->start - offset;
119 resource_size_t phys_addr = res->start;
Joe Perches28f65c112011-06-09 09:13:32 -0700120 resource_size_t size = resource_size(res);
Trent Piephoa097a782009-01-06 22:37:53 -0600121 u32 flags = 0x80044000; /* enable & mem R/W */
122 unsigned int i;
123
124 pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n",
125 (u64)res->start, (u64)size);
126
Trent Piepho565f3762008-12-17 11:43:26 -0800127 if (res->flags & IORESOURCE_PREFETCH)
128 flags |= 0x10000000; /* enable relaxed ordering */
129
Trent Piephoa097a782009-01-06 22:37:53 -0600130 for (i = 0; size > 0; i++) {
131 unsigned int bits = min(__ilog2(size),
132 __ffs(pci_addr | phys_addr));
133
134 if (index + i >= 5)
135 return -1;
136
137 out_be32(&pci->pow[index + i].potar, pci_addr >> 12);
138 out_be32(&pci->pow[index + i].potear, (u64)pci_addr >> 44);
139 out_be32(&pci->pow[index + i].powbar, phys_addr >> 12);
140 out_be32(&pci->pow[index + i].powar, flags | (bits - 1));
141
142 pci_addr += (resource_size_t)1U << bits;
143 phys_addr += (resource_size_t)1U << bits;
144 size -= (resource_size_t)1U << bits;
145 }
146
147 return i;
148}
149
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800150/* atmu setup for fsl pci/pcie controller */
Jia Hongtaoa393d892012-11-08 10:11:07 +0800151static void setup_pci_atmu(struct pci_controller *hose,
Anton Vorontsovc9dadff2008-12-29 19:40:32 +0300152 struct resource *rsrc)
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500153{
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800154 struct ccsr_pci __iomem *pci;
Prabhakar Kushwahaf4154e12011-02-24 15:05:04 +0530155 int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
Kumar Gala54c18192009-05-08 15:05:23 -0500156 u64 mem, sz, paddr_hi = 0;
157 u64 paddr_lo = ULLONG_MAX;
158 u32 pcicsrbar = 0, pcicsrbar_sz;
159 u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
160 PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
Grant Likelyc22618a2012-11-14 22:37:12 +0000161 const char *name = hose->dn->full_name;
Timur Tabi446bc1f2011-12-13 14:51:59 -0600162 const u64 *reg;
163 int len;
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500164
Kumar Gala72b122c2008-01-14 17:02:19 -0600165 pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
Joe Perches28f65c112011-06-09 09:13:32 -0700166 (u64)rsrc->start, (u64)resource_size(rsrc));
Prabhakar Kushwahaf4154e12011-02-24 15:05:04 +0530167
Joe Perches28f65c112011-06-09 09:13:32 -0700168 pci = ioremap(rsrc->start, resource_size(rsrc));
Trent Piephoa097a782009-01-06 22:37:53 -0600169 if (!pci) {
170 dev_err(hose->parent, "Unable to map ATMU registers\n");
171 return;
172 }
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500173
Roy Zang9e678862012-09-03 17:22:10 +0800174 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
175 if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
176 win_idx = 2;
177 start_idx = 0;
178 end_idx = 3;
179 }
180 }
181
Trent Piephoa097a782009-01-06 22:37:53 -0600182 /* Disable all windows (except powar0 since it's ignored) */
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800183 for(i = 1; i < 5; i++)
184 out_be32(&pci->pow[i].powar, 0);
Prabhakar Kushwahaf4154e12011-02-24 15:05:04 +0530185 for (i = start_idx; i < end_idx; i++)
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800186 out_be32(&pci->piw[i].piwar, 0);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500187
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800188 /* Setup outbound MEM window */
Trent Piephoa097a782009-01-06 22:37:53 -0600189 for(i = 0, j = 1; i < 3; i++) {
190 if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
191 continue;
192
Kumar Gala54c18192009-05-08 15:05:23 -0500193 paddr_lo = min(paddr_lo, (u64)hose->mem_resources[i].start);
194 paddr_hi = max(paddr_hi, (u64)hose->mem_resources[i].end);
195
Trent Piephoa097a782009-01-06 22:37:53 -0600196 n = setup_one_atmu(pci, j, &hose->mem_resources[i],
197 hose->pci_mem_offset);
198
199 if (n < 0 || j >= 5) {
200 pr_err("Ran out of outbound PCI ATMUs for resource %d!\n", i);
201 hose->mem_resources[i].flags |= IORESOURCE_DISABLED;
202 } else
203 j += n;
204 }
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500205
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800206 /* Setup outbound IO window */
Trent Piephoa097a782009-01-06 22:37:53 -0600207 if (hose->io_resource.flags & IORESOURCE_IO) {
208 if (j >= 5) {
209 pr_err("Ran out of outbound PCI ATMUs for IO resource\n");
210 } else {
211 pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, "
212 "phy base 0x%016llx.\n",
Joe Perches28f65c112011-06-09 09:13:32 -0700213 (u64)hose->io_resource.start,
214 (u64)resource_size(&hose->io_resource),
215 (u64)hose->io_base_phys);
Trent Piephoa097a782009-01-06 22:37:53 -0600216 out_be32(&pci->pow[j].potar, (hose->io_resource.start >> 12));
217 out_be32(&pci->pow[j].potear, 0);
218 out_be32(&pci->pow[j].powbar, (hose->io_base_phys >> 12));
219 /* Enable, IO R/W */
220 out_be32(&pci->pow[j].powar, 0x80088000
221 | (__ilog2(hose->io_resource.end
222 - hose->io_resource.start + 1) - 1));
223 }
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800224 }
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500225
Kumar Gala54c18192009-05-08 15:05:23 -0500226 /* convert to pci address space */
227 paddr_hi -= hose->pci_mem_offset;
228 paddr_lo -= hose->pci_mem_offset;
Trent Piephoa097a782009-01-06 22:37:53 -0600229
Kumar Gala54c18192009-05-08 15:05:23 -0500230 if (paddr_hi == paddr_lo) {
231 pr_err("%s: No outbound window space\n", name);
Julia Lawall0cf572d2012-01-12 10:55:14 +0100232 goto out;
Kumar Gala54c18192009-05-08 15:05:23 -0500233 }
234
235 if (paddr_lo == 0) {
236 pr_err("%s: No space for inbound window\n", name);
Julia Lawall0cf572d2012-01-12 10:55:14 +0100237 goto out;
Kumar Gala54c18192009-05-08 15:05:23 -0500238 }
239
240 /* setup PCSRBAR/PEXCSRBAR */
241 early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, 0xffffffff);
242 early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, &pcicsrbar_sz);
243 pcicsrbar_sz = ~pcicsrbar_sz + 1;
244
245 if (paddr_hi < (0x100000000ull - pcicsrbar_sz) ||
246 (paddr_lo > 0x100000000ull))
247 pcicsrbar = 0x100000000ull - pcicsrbar_sz;
248 else
249 pcicsrbar = (paddr_lo - pcicsrbar_sz) & -pcicsrbar_sz;
250 early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, pcicsrbar);
251
252 paddr_lo = min(paddr_lo, (u64)pcicsrbar);
253
254 pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar);
255
256 /* Setup inbound mem window */
Yinghai Lu95f72d12010-07-12 14:36:09 +1000257 mem = memblock_end_of_DRAM();
Timur Tabi446bc1f2011-12-13 14:51:59 -0600258
259 /*
260 * The msi-address-64 property, if it exists, indicates the physical
261 * address of the MSIIR register. Normally, this register is located
262 * inside CCSR, so the ATMU that covers all of CCSR is used. But if
263 * this property exists, then we normally need to create a new ATMU
264 * for it. For now, however, we cheat. The only entity that creates
265 * this property is the Freescale hypervisor, and the address is
266 * specified in the partition configuration. Typically, the address
267 * is located in the page immediately after the end of DDR. If so, we
268 * can avoid allocating a new ATMU by extending the DDR ATMU by one
269 * page.
270 */
271 reg = of_get_property(hose->dn, "msi-address-64", &len);
272 if (reg && (len == sizeof(u64))) {
273 u64 address = be64_to_cpup(reg);
274
275 if ((address >= mem) && (address < (mem + PAGE_SIZE))) {
276 pr_info("%s: extending DDR ATMU to cover MSIIR", name);
277 mem += PAGE_SIZE;
278 } else {
279 /* TODO: Create a new ATMU for MSIIR */
280 pr_warn("%s: msi-address-64 address of %llx is "
281 "unsupported\n", name, address);
282 }
283 }
284
Kumar Gala54c18192009-05-08 15:05:23 -0500285 sz = min(mem, paddr_lo);
286 mem_log = __ilog2_u64(sz);
287
288 /* PCIe can overmap inbound & outbound since RX & TX are separated */
289 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
290 /* Size window to exact size if power-of-two or one size up */
291 if ((1ull << mem_log) != mem) {
292 if ((1ull << mem_log) > mem)
293 pr_info("%s: Setting PCI inbound window "
294 "greater than memory size\n", name);
295 mem_log++;
296 }
297
Prabhakar Kushwahaf4154e12011-02-24 15:05:04 +0530298 piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
Kumar Gala54c18192009-05-08 15:05:23 -0500299
300 /* Setup inbound memory window */
301 out_be32(&pci->piw[win_idx].pitar, 0x00000000);
302 out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
303 out_be32(&pci->piw[win_idx].piwar, piwar);
304 win_idx--;
305
306 hose->dma_window_base_cur = 0x00000000;
307 hose->dma_window_size = (resource_size_t)sz;
Kumar Gala96ea3b42011-11-30 23:38:18 -0600308
309 /*
310 * if we have >4G of memory setup second PCI inbound window to
311 * let devices that are 64-bit address capable to work w/o
312 * SWIOTLB and access the full range of memory
313 */
314 if (sz != mem) {
315 mem_log = __ilog2_u64(mem);
316
317 /* Size window up if we dont fit in exact power-of-2 */
318 if ((1ull << mem_log) != mem)
319 mem_log++;
320
321 piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
322
323 /* Setup inbound memory window */
324 out_be32(&pci->piw[win_idx].pitar, 0x00000000);
325 out_be32(&pci->piw[win_idx].piwbear,
326 pci64_dma_offset >> 44);
327 out_be32(&pci->piw[win_idx].piwbar,
328 pci64_dma_offset >> 12);
329 out_be32(&pci->piw[win_idx].piwar, piwar);
330
331 /*
332 * install our own dma_set_mask handler to fixup dma_ops
333 * and dma_offset
334 */
335 ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
336
337 pr_info("%s: Setup 64-bit PCI DMA window\n", name);
338 }
Kumar Gala54c18192009-05-08 15:05:23 -0500339 } else {
340 u64 paddr = 0;
341
342 /* Setup inbound memory window */
343 out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
344 out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
345 out_be32(&pci->piw[win_idx].piwar, (piwar | (mem_log - 1)));
346 win_idx--;
347
348 paddr += 1ull << mem_log;
349 sz -= 1ull << mem_log;
350
351 if (sz) {
352 mem_log = __ilog2_u64(sz);
353 piwar |= (mem_log - 1);
354
355 out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
356 out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
357 out_be32(&pci->piw[win_idx].piwar, piwar);
358 win_idx--;
359
360 paddr += 1ull << mem_log;
361 }
362
363 hose->dma_window_base_cur = 0x00000000;
364 hose->dma_window_size = (resource_size_t)paddr;
365 }
366
367 if (hose->dma_window_size < mem) {
368#ifndef CONFIG_SWIOTLB
369 pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to "
370 "map - enable CONFIG_SWIOTLB to avoid dma errors.\n",
371 name);
372#endif
373 /* adjusting outbound windows could reclaim space in mem map */
374 if (paddr_hi < 0xffffffffull)
375 pr_warning("%s: WARNING: Outbound window cfg leaves "
376 "gaps in memory map. Adjusting the memory map "
377 "could reduce unnecessary bounce buffering.\n",
378 name);
379
380 pr_info("%s: DMA window size is 0x%llx\n", name,
381 (u64)hose->dma_window_size);
382 }
Becky Bruce89d93342009-04-20 11:26:48 -0500383
Julia Lawall0cf572d2012-01-12 10:55:14 +0100384out:
Trent Piephoa097a782009-01-06 22:37:53 -0600385 iounmap(pci);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500386}
387
Anton Vorontsovc9dadff2008-12-29 19:40:32 +0300388static void __init setup_pci_cmd(struct pci_controller *hose)
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500389{
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500390 u16 cmd;
Kumar Galaeb12af42007-07-20 16:29:09 -0500391 int cap_x;
392
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500393 early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd);
394 cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800395 | PCI_COMMAND_IO;
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500396 early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
Kumar Galaeb12af42007-07-20 16:29:09 -0500397
398 cap_x = early_find_capability(hose, 0, 0, PCI_CAP_ID_PCIX);
399 if (cap_x) {
400 int pci_x_cmd = cap_x + PCI_X_CMD;
401 cmd = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
402 | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
403 early_write_config_word(hose, 0, 0, pci_x_cmd, cmd);
404 } else {
405 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
406 }
Kumar Gala9ad494f2006-06-28 00:37:45 -0500407}
408
Kumar Gala6c0a11c2007-07-19 15:29:53 -0500409void fsl_pcibios_fixup_bus(struct pci_bus *bus)
410{
Kumar Gala8206a112009-04-30 03:10:08 +0000411 struct pci_controller *hose = pci_bus_to_host(bus);
Benjamin Herrenschmidt13635df2012-02-14 18:22:20 +0000412 int i, is_pcie = 0, no_link;
Kumar Gala6c0a11c2007-07-19 15:29:53 -0500413
Benjamin Herrenschmidt13635df2012-02-14 18:22:20 +0000414 /* The root complex bridge comes up with bogus resources,
415 * we copy the PHB ones in.
416 *
417 * With the current generic PCI code, the PHB bus no longer
418 * has bus->resource[0..4] set, so things are a bit more
419 * tricky.
420 */
421
422 if (fsl_pcie_bus_fixup)
423 is_pcie = early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP);
424 no_link = !!(hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK);
425
426 if (bus->parent == hose->bus && (is_pcie || no_link)) {
427 for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; ++i) {
Kumar Gala72b122c2008-01-14 17:02:19 -0600428 struct resource *res = bus->resource[i];
Benjamin Herrenschmidt13635df2012-02-14 18:22:20 +0000429 struct resource *par;
430
431 if (!res)
432 continue;
433 if (i == 0)
434 par = &hose->io_resource;
435 else if (i < 4)
436 par = &hose->mem_resources[i-1];
437 else par = NULL;
438
439 res->start = par ? par->start : 0;
440 res->end = par ? par->end : 0;
441 res->flags = par ? par->flags : 0;
Kumar Gala6c0a11c2007-07-19 15:29:53 -0500442 }
443 }
444}
445
Varun Sethi52c5aff2013-01-14 16:58:00 +0530446int __init fsl_add_bridge(struct platform_device *pdev, int is_primary)
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500447{
448 int len;
449 struct pci_controller *hose;
450 struct resource rsrc;
Jeremy Kerr8efca492006-07-12 15:39:42 +1000451 const int *bus_range;
Minghuan Lian59c58c32012-09-24 13:50:52 +0800452 u8 hdr_type, progif;
Varun Sethi52c5aff2013-01-14 16:58:00 +0530453 struct device_node *dev;
454
455 dev = pdev->dev.of_node;
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500456
Prabhakar Kushwahaef1fd2d2011-03-31 12:31:09 +0530457 if (!of_device_is_available(dev)) {
458 pr_warning("%s: disabled\n", dev->full_name);
459 return -ENODEV;
460 }
461
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800462 pr_debug("Adding PCI host bridge %s\n", dev->full_name);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500463
464 /* Fetch host bridge registers address */
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800465 if (of_address_to_resource(dev, 0, &rsrc)) {
466 printk(KERN_WARNING "Can't get pci register base!");
467 return -ENOMEM;
468 }
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500469
470 /* Get bus range if any */
Stephen Rothwelle2eb6392007-04-03 22:26:41 +1000471 bus_range = of_get_property(dev, "bus-range", &len);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500472 if (bus_range == NULL || len < 2 * sizeof(int))
473 printk(KERN_WARNING "Can't get bus-range for %s, assume"
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800474 " bus 0\n", dev->full_name);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500475
Rob Herring0e47ff12011-07-12 09:25:51 -0500476 pci_add_flags(PCI_REASSIGN_ALL_BUS);
Kumar Galadbf84712007-06-27 01:56:50 -0500477 hose = pcibios_alloc_controller(dev);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500478 if (!hose)
479 return -ENOMEM;
Kumar Galadbf84712007-06-27 01:56:50 -0500480
Varun Sethi52c5aff2013-01-14 16:58:00 +0530481 /* set platform device as the parent */
482 hose->parent = &pdev->dev;
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500483 hose->first_busno = bus_range ? bus_range[0] : 0x0;
Zhang Weibf7c0362007-05-22 11:38:26 +0800484 hose->last_busno = bus_range ? bus_range[1] : 0xff;
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500485
Kumar Gala2e56ff22007-07-19 16:07:35 -0500486 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
487 PPC_INDIRECT_TYPE_BIG_ENDIAN);
Prabhakar Kushwaha08871c02011-05-23 15:53:25 +0530488
Minghuan Lian59c58c32012-09-24 13:50:52 +0800489 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
490 /* For PCIE read HEADER_TYPE to identify controler mode */
491 early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
492 if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
493 goto no_bridge;
494
495 } else {
496 /* For PCI read PROG to identify controller mode */
497 early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
498 if ((progif & 1) == 1)
499 goto no_bridge;
Prabhakar Kushwaha08871c02011-05-23 15:53:25 +0530500 }
501
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800502 setup_pci_cmd(hose);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500503
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800504 /* check PCI express link status */
Kumar Gala957ecff2007-07-11 13:31:58 -0500505 if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
Kumar Gala7659c032007-07-25 00:29:53 -0500506 hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
Kumar Gala957ecff2007-07-11 13:31:58 -0500507 PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
Roy ZANGcc6ea0d2012-09-21 04:12:52 +0000508 if (fsl_pcie_check_link(hose, &rsrc))
Kumar Gala957ecff2007-07-11 13:31:58 -0500509 hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
510 }
Zhang Weie4725c22007-06-25 15:21:10 -0500511
joe@perches.comdf3c9012007-11-20 12:47:55 +1100512 printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800513 "Firmware bus number: %d->%d\n",
514 (unsigned long long)rsrc.start, hose->first_busno,
515 hose->last_busno);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500516
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800517 pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500518 hose, hose->cfg_addr, hose->cfg_data);
519
520 /* Interpret the "ranges" property */
521 /* This also maps the I/O region and sets isa_io/mem_base */
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800522 pci_process_bridge_OF_ranges(hose, dev, is_primary);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500523
524 /* Setup PEX window registers */
Zang Roy-r619119ac4dd32007-07-10 18:46:35 +0800525 setup_pci_atmu(hose, &rsrc);
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500526
527 return 0;
Minghuan Lian59c58c32012-09-24 13:50:52 +0800528
529no_bridge:
530 /* unmap cfg_data & cfg_addr separately if not on same page */
531 if (((unsigned long)hose->cfg_data & PAGE_MASK) !=
532 ((unsigned long)hose->cfg_addr & PAGE_MASK))
533 iounmap(hose->cfg_data);
534 iounmap(hose->cfg_addr);
535 pcibios_free_controller(hose);
536 return -ENODEV;
Jon Loeligerb809b3e2006-06-17 17:52:48 -0500537}
Kumar Gala5753c082009-10-16 18:31:48 -0500538#endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
John Rigby76fe1ff2008-06-26 11:07:57 -0600539
Kumar Gala470788d2011-05-19 19:56:50 -0500540DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
Anton Vorontsov598804c2009-01-09 00:55:39 +0300541
Kumar Gala470788d2011-05-19 19:56:50 -0500542#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
Anton Vorontsov598804c2009-01-09 00:55:39 +0300543struct mpc83xx_pcie_priv {
544 void __iomem *cfg_type0;
545 void __iomem *cfg_type1;
546 u32 dev_base;
547};
548
Kumar Galab8f44ec2010-08-05 02:45:08 -0500549struct pex_inbound_window {
550 u32 ar;
551 u32 tar;
552 u32 barl;
553 u32 barh;
554};
555
Anton Vorontsov598804c2009-01-09 00:55:39 +0300556/*
557 * With the convention of u-boot, the PCIE outbound window 0 serves
558 * as configuration transactions outbound.
559 */
560#define PEX_OUTWIN0_BAR 0xCA4
561#define PEX_OUTWIN0_TAL 0xCA8
562#define PEX_OUTWIN0_TAH 0xCAC
Kumar Galab8f44ec2010-08-05 02:45:08 -0500563#define PEX_RC_INWIN_BASE 0xE60
564#define PEX_RCIWARn_EN 0x1
Anton Vorontsov598804c2009-01-09 00:55:39 +0300565
566static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
567{
Kumar Gala8206a112009-04-30 03:10:08 +0000568 struct pci_controller *hose = pci_bus_to_host(bus);
Anton Vorontsov598804c2009-01-09 00:55:39 +0300569
570 if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
571 return PCIBIOS_DEVICE_NOT_FOUND;
572 /*
573 * Workaround for the HW bug: for Type 0 configure transactions the
574 * PCI-E controller does not check the device number bits and just
575 * assumes that the device number bits are 0.
576 */
577 if (bus->number == hose->first_busno ||
578 bus->primary == hose->first_busno) {
579 if (devfn & 0xf8)
580 return PCIBIOS_DEVICE_NOT_FOUND;
581 }
582
583 if (ppc_md.pci_exclude_device) {
584 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
585 return PCIBIOS_DEVICE_NOT_FOUND;
586 }
587
588 return PCIBIOS_SUCCESSFUL;
589}
590
591static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
592 unsigned int devfn, int offset)
593{
Kumar Gala8206a112009-04-30 03:10:08 +0000594 struct pci_controller *hose = pci_bus_to_host(bus);
Anton Vorontsov598804c2009-01-09 00:55:39 +0300595 struct mpc83xx_pcie_priv *pcie = hose->dn->data;
Anton Vorontsovf93611f2009-12-08 01:54:35 +0300596 u32 dev_base = bus->number << 24 | devfn << 16;
Anton Vorontsov598804c2009-01-09 00:55:39 +0300597 int ret;
598
599 ret = mpc83xx_pcie_exclude_device(bus, devfn);
600 if (ret)
601 return NULL;
602
603 offset &= 0xfff;
604
605 /* Type 0 */
606 if (bus->number == hose->first_busno)
607 return pcie->cfg_type0 + offset;
608
609 if (pcie->dev_base == dev_base)
610 goto mapped;
611
612 out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, dev_base);
613
614 pcie->dev_base = dev_base;
615mapped:
616 return pcie->cfg_type1 + offset;
617}
618
619static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
620 int offset, int len, u32 *val)
621{
622 void __iomem *cfg_addr;
623
624 cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
625 if (!cfg_addr)
626 return PCIBIOS_DEVICE_NOT_FOUND;
627
628 switch (len) {
629 case 1:
630 *val = in_8(cfg_addr);
631 break;
632 case 2:
633 *val = in_le16(cfg_addr);
634 break;
635 default:
636 *val = in_le32(cfg_addr);
637 break;
638 }
639
640 return PCIBIOS_SUCCESSFUL;
641}
642
643static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
644 int offset, int len, u32 val)
645{
Anton Vorontsovf93611f2009-12-08 01:54:35 +0300646 struct pci_controller *hose = pci_bus_to_host(bus);
Anton Vorontsov598804c2009-01-09 00:55:39 +0300647 void __iomem *cfg_addr;
648
649 cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
650 if (!cfg_addr)
651 return PCIBIOS_DEVICE_NOT_FOUND;
652
Anton Vorontsovf93611f2009-12-08 01:54:35 +0300653 /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */
654 if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno)
655 val &= 0xffffff00;
656
Anton Vorontsov598804c2009-01-09 00:55:39 +0300657 switch (len) {
658 case 1:
659 out_8(cfg_addr, val);
660 break;
661 case 2:
662 out_le16(cfg_addr, val);
663 break;
664 default:
665 out_le32(cfg_addr, val);
666 break;
667 }
668
669 return PCIBIOS_SUCCESSFUL;
670}
671
672static struct pci_ops mpc83xx_pcie_ops = {
673 .read = mpc83xx_pcie_read_config,
674 .write = mpc83xx_pcie_write_config,
675};
676
677static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
678 struct resource *reg)
679{
680 struct mpc83xx_pcie_priv *pcie;
681 u32 cfg_bar;
682 int ret = -ENOMEM;
683
684 pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL);
685 if (!pcie)
686 return ret;
687
688 pcie->cfg_type0 = ioremap(reg->start, resource_size(reg));
689 if (!pcie->cfg_type0)
690 goto err0;
691
692 cfg_bar = in_le32(pcie->cfg_type0 + PEX_OUTWIN0_BAR);
693 if (!cfg_bar) {
694 /* PCI-E isn't configured. */
695 ret = -ENODEV;
696 goto err1;
697 }
698
699 pcie->cfg_type1 = ioremap(cfg_bar, 0x1000);
700 if (!pcie->cfg_type1)
701 goto err1;
702
703 WARN_ON(hose->dn->data);
704 hose->dn->data = pcie;
705 hose->ops = &mpc83xx_pcie_ops;
706
707 out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0);
708 out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);
709
Roy ZANGcc6ea0d2012-09-21 04:12:52 +0000710 if (fsl_pcie_check_link(hose, NULL))
Anton Vorontsov598804c2009-01-09 00:55:39 +0300711 hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
712
713 return 0;
714err1:
715 iounmap(pcie->cfg_type0);
716err0:
717 kfree(pcie);
718 return ret;
719
720}
721
John Rigby76fe1ff2008-06-26 11:07:57 -0600722int __init mpc83xx_add_bridge(struct device_node *dev)
723{
Anton Vorontsov598804c2009-01-09 00:55:39 +0300724 int ret;
John Rigby76fe1ff2008-06-26 11:07:57 -0600725 int len;
726 struct pci_controller *hose;
John Rigby5b70a092008-10-07 13:00:18 -0600727 struct resource rsrc_reg;
728 struct resource rsrc_cfg;
John Rigby76fe1ff2008-06-26 11:07:57 -0600729 const int *bus_range;
John Rigby5b70a092008-10-07 13:00:18 -0600730 int primary;
John Rigby76fe1ff2008-06-26 11:07:57 -0600731
Kumar Galab8f44ec2010-08-05 02:45:08 -0500732 is_mpc83xx_pci = 1;
733
Anton Vorontsov598804c2009-01-09 00:55:39 +0300734 if (!of_device_is_available(dev)) {
735 pr_warning("%s: disabled by the firmware.\n",
736 dev->full_name);
737 return -ENODEV;
738 }
John Rigby76fe1ff2008-06-26 11:07:57 -0600739 pr_debug("Adding PCI host bridge %s\n", dev->full_name);
740
741 /* Fetch host bridge registers address */
John Rigby5b70a092008-10-07 13:00:18 -0600742 if (of_address_to_resource(dev, 0, &rsrc_reg)) {
743 printk(KERN_WARNING "Can't get pci register base!\n");
744 return -ENOMEM;
745 }
746
747 memset(&rsrc_cfg, 0, sizeof(rsrc_cfg));
748
749 if (of_address_to_resource(dev, 1, &rsrc_cfg)) {
750 printk(KERN_WARNING
751 "No pci config register base in dev tree, "
752 "using default\n");
753 /*
754 * MPC83xx supports up to two host controllers
755 * one at 0x8500 has config space registers at 0x8300
756 * one at 0x8600 has config space registers at 0x8380
757 */
758 if ((rsrc_reg.start & 0xfffff) == 0x8500)
759 rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8300;
760 else if ((rsrc_reg.start & 0xfffff) == 0x8600)
761 rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8380;
762 }
763 /*
764 * Controller at offset 0x8500 is primary
765 */
766 if ((rsrc_reg.start & 0xfffff) == 0x8500)
767 primary = 1;
768 else
769 primary = 0;
John Rigby76fe1ff2008-06-26 11:07:57 -0600770
771 /* Get bus range if any */
772 bus_range = of_get_property(dev, "bus-range", &len);
773 if (bus_range == NULL || len < 2 * sizeof(int)) {
774 printk(KERN_WARNING "Can't get bus-range for %s, assume"
775 " bus 0\n", dev->full_name);
776 }
777
Rob Herring0e47ff12011-07-12 09:25:51 -0500778 pci_add_flags(PCI_REASSIGN_ALL_BUS);
John Rigby76fe1ff2008-06-26 11:07:57 -0600779 hose = pcibios_alloc_controller(dev);
780 if (!hose)
781 return -ENOMEM;
782
783 hose->first_busno = bus_range ? bus_range[0] : 0;
784 hose->last_busno = bus_range ? bus_range[1] : 0xff;
785
Anton Vorontsov598804c2009-01-09 00:55:39 +0300786 if (of_device_is_compatible(dev, "fsl,mpc8314-pcie")) {
787 ret = mpc83xx_pcie_setup(hose, &rsrc_reg);
788 if (ret)
789 goto err0;
790 } else {
791 setup_indirect_pci(hose, rsrc_cfg.start,
792 rsrc_cfg.start + 4, 0);
793 }
John Rigby76fe1ff2008-06-26 11:07:57 -0600794
John Rigby35225802008-10-07 15:13:18 -0600795 printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
John Rigby76fe1ff2008-06-26 11:07:57 -0600796 "Firmware bus number: %d->%d\n",
John Rigby5b70a092008-10-07 13:00:18 -0600797 (unsigned long long)rsrc_reg.start, hose->first_busno,
John Rigby76fe1ff2008-06-26 11:07:57 -0600798 hose->last_busno);
799
800 pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
801 hose, hose->cfg_addr, hose->cfg_data);
802
803 /* Interpret the "ranges" property */
804 /* This also maps the I/O region and sets isa_io/mem_base */
805 pci_process_bridge_OF_ranges(hose, dev, primary);
806
807 return 0;
Anton Vorontsov598804c2009-01-09 00:55:39 +0300808err0:
809 pcibios_free_controller(hose);
810 return ret;
John Rigby76fe1ff2008-06-26 11:07:57 -0600811}
812#endif /* CONFIG_PPC_83xx */
Kumar Galab8f44ec2010-08-05 02:45:08 -0500813
814u64 fsl_pci_immrbar_base(struct pci_controller *hose)
815{
816#ifdef CONFIG_PPC_83xx
817 if (is_mpc83xx_pci) {
818 struct mpc83xx_pcie_priv *pcie = hose->dn->data;
819 struct pex_inbound_window *in;
820 int i;
821
822 /* Walk the Root Complex Inbound windows to match IMMR base */
823 in = pcie->cfg_type0 + PEX_RC_INWIN_BASE;
824 for (i = 0; i < 4; i++) {
825 /* not enabled, skip */
826 if (!in_le32(&in[i].ar) & PEX_RCIWARn_EN)
827 continue;
828
829 if (get_immrbase() == in_le32(&in[i].tar))
830 return (u64)in_le32(&in[i].barh) << 32 |
831 in_le32(&in[i].barl);
832 }
833
834 printk(KERN_WARNING "could not find PCI BAR matching IMMR\n");
835 }
836#endif
837
838#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
839 if (!is_mpc83xx_pci) {
840 u32 base;
841
842 pci_bus_read_config_dword(hose->bus,
843 PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
844 return base;
845 }
846#endif
847
848 return 0;
849}
Scott Wood07e4f802012-07-10 19:26:47 -0500850
851#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
852static const struct of_device_id pci_ids[] = {
853 { .compatible = "fsl,mpc8540-pci", },
854 { .compatible = "fsl,mpc8548-pcie", },
855 { .compatible = "fsl,mpc8610-pci", },
856 { .compatible = "fsl,mpc8641-pcie", },
Timur Tabi14bdc912013-01-17 16:34:32 -0600857 { .compatible = "fsl,qoriq-pcie-v2.1", },
Scott Wood07e4f802012-07-10 19:26:47 -0500858 { .compatible = "fsl,qoriq-pcie-v2.2", },
Timur Tabi14bdc912013-01-17 16:34:32 -0600859 { .compatible = "fsl,qoriq-pcie-v2.3", },
860 { .compatible = "fsl,qoriq-pcie-v2.4", },
Roy ZANGcc6ea0d2012-09-21 04:12:52 +0000861 { .compatible = "fsl,qoriq-pcie-v3.0", },
Timur Tabi14bdc912013-01-17 16:34:32 -0600862
863 /*
864 * The following entries are for compatibility with older device
865 * trees.
866 */
867 { .compatible = "fsl,p1022-pcie", },
868 { .compatible = "fsl,p4080-pcie", },
869
Scott Wood07e4f802012-07-10 19:26:47 -0500870 {},
871};
872
873struct device_node *fsl_pci_primary;
874
Jia Hongtao905e75c2012-08-28 15:44:08 +0800875void fsl_pci_assign_primary(void)
876{
877 struct device_node *np;
878
879 /* Callers can specify the primary bus using other means. */
880 if (fsl_pci_primary)
881 return;
882
883 /* If a PCI host bridge contains an ISA node, it's primary. */
884 np = of_find_node_by_type(NULL, "isa");
885 while ((fsl_pci_primary = of_get_parent(np))) {
886 of_node_put(np);
887 np = fsl_pci_primary;
888
889 if (of_match_node(pci_ids, np) && of_device_is_available(np))
890 return;
891 }
892
893 /*
894 * If there's no PCI host bridge with ISA, arbitrarily
895 * designate one as primary. This can go away once
896 * various bugs with primary-less systems are fixed.
897 */
898 for_each_matching_node(np, pci_ids) {
899 if (of_device_is_available(np)) {
900 fsl_pci_primary = np;
901 of_node_put(np);
902 return;
903 }
904 }
905}
906
Greg Kroah-Hartmancad5cef2012-12-21 14:04:10 -0800907static int fsl_pci_probe(struct platform_device *pdev)
Scott Wood07e4f802012-07-10 19:26:47 -0500908{
Jia Hongtaoc9f11c32012-08-03 18:14:09 +0800909 int ret;
Scott Wood07e4f802012-07-10 19:26:47 -0500910 struct device_node *node;
Jia Hongtao4d56dec2012-09-18 17:57:48 +0800911#ifdef CONFIG_SWIOTLB
Scott Wood07e4f802012-07-10 19:26:47 -0500912 struct pci_controller *hose;
Jia Hongtao4d56dec2012-09-18 17:57:48 +0800913#endif
Scott Wood07e4f802012-07-10 19:26:47 -0500914
Jia Hongtao905e75c2012-08-28 15:44:08 +0800915 node = pdev->dev.of_node;
Varun Sethi52c5aff2013-01-14 16:58:00 +0530916 ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
Scott Wood07e4f802012-07-10 19:26:47 -0500917
918#ifdef CONFIG_SWIOTLB
Jia Hongtao905e75c2012-08-28 15:44:08 +0800919 if (ret == 0) {
920 hose = pci_find_hose_for_OF_device(pdev->dev.of_node);
921
922 /*
923 * if we couldn't map all of DRAM via the dma windows
924 * we need SWIOTLB to handle buffers located outside of
925 * dma capable memory region
926 */
927 if (memblock_end_of_DRAM() - 1 > hose->dma_window_base_cur +
928 hose->dma_window_size)
929 ppc_swiotlb_enable = 1;
930 }
Scott Wood07e4f802012-07-10 19:26:47 -0500931#endif
Jia Hongtao905e75c2012-08-28 15:44:08 +0800932
933 mpc85xx_pci_err_probe(pdev);
934
935 return 0;
Scott Wood07e4f802012-07-10 19:26:47 -0500936}
Jia Hongtao905e75c2012-08-28 15:44:08 +0800937
Jia Hongtaoa393d892012-11-08 10:11:07 +0800938#ifdef CONFIG_PM
939static int fsl_pci_resume(struct device *dev)
940{
941 struct pci_controller *hose;
942 struct resource pci_rsrc;
943
944 hose = pci_find_hose_for_OF_device(dev->of_node);
945 if (!hose)
946 return -ENODEV;
947
948 if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
949 dev_err(dev, "Get pci register base failed.");
950 return -ENODEV;
951 }
952
953 setup_pci_atmu(hose, &pci_rsrc);
954
955 return 0;
956}
957
958static const struct dev_pm_ops pci_pm_ops = {
959 .resume = fsl_pci_resume,
960};
961
962#define PCI_PM_OPS (&pci_pm_ops)
963
964#else
965
966#define PCI_PM_OPS NULL
967
968#endif
969
Jia Hongtao905e75c2012-08-28 15:44:08 +0800970static struct platform_driver fsl_pci_driver = {
971 .driver = {
972 .name = "fsl-pci",
Jia Hongtaoa393d892012-11-08 10:11:07 +0800973 .pm = PCI_PM_OPS,
Jia Hongtao905e75c2012-08-28 15:44:08 +0800974 .of_match_table = pci_ids,
975 },
976 .probe = fsl_pci_probe,
977};
978
979static int __init fsl_pci_init(void)
980{
981 return platform_driver_register(&fsl_pci_driver);
982}
983arch_initcall(fsl_pci_init);
Scott Wood07e4f802012-07-10 19:26:47 -0500984#endif