aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-03-27 14:51:41 -0400
committerNicolas Pitre <nico@marvell.com>2008-03-27 14:51:41 -0400
commitd50c60a87a95a42f1bc984150d3eebc77a0b0c14 (patch)
treee6ad641c497fb150aaf2ffa0f8fa6e4604f64aaf /arch/arm
parenta99842704a031ac23d4f7344e412a44bb3beb3b3 (diff)
Orion: enable access to local config space
This patch enables access to the local PCIe/PCI configuration space, and is necessary for such things as PCI Advanced Error Recovery to work. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Reviewed-by: Tzachi Perelstein <tzachi@marvell.com> Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Nicolas Pitre <nico@marvell.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-orion/pci.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/arch/arm/mach-orion/pci.c b/arch/arm/mach-orion/pci.c
index 18cdf3b505a5..e3aab14b943c 100644
--- a/arch/arm/mach-orion/pci.c
+++ b/arch/arm/mach-orion/pci.c
@@ -50,15 +50,18 @@ static int pcie_valid_config(int bus, int dev)
50{ 50{
51 /* 51 /*
52 * Don't go out when trying to access -- 52 * Don't go out when trying to access --
53 * 1. our own device / nonexisting device on local bus 53 * 1. nonexisting device on local bus
54 * 2. where there's no device connected (no link) 54 * 2. where there's no device connected (no link)
55 */ 55 */
56 if (bus == 0 && dev != 1) 56 if (bus == 0 && dev == 0)
57 return 0; 57 return 1;
58 58
59 if (!orion_pcie_link_up(PCIE_BASE)) 59 if (!orion_pcie_link_up(PCIE_BASE))
60 return 0; 60 return 0;
61 61
62 if (bus == 0 && dev != 1)
63 return 0;
64
62 return 1; 65 return 1;
63} 66}
64 67
@@ -272,12 +275,6 @@ int orion_pci_local_bus_nr(void)
272 return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); 275 return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
273} 276}
274 277
275static int orion_pci_local_dev_nr(void)
276{
277 u32 conf = orion_read(PCI_P2P_CONF);
278 return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS);
279}
280
281static int orion_pci_hw_rd_conf(int bus, int dev, u32 func, 278static int orion_pci_hw_rd_conf(int bus, int dev, u32 func,
282 u32 where, u32 size, u32 *val) 279 u32 where, u32 size, u32 *val)
283{ 280{
@@ -333,8 +330,8 @@ static int orion_pci_rd_conf(struct pci_bus *bus, u32 devfn,
333 /* 330 /*
334 * Don't go out for local device 331 * Don't go out for local device
335 */ 332 */
336 if ((orion_pci_local_bus_nr() == bus->number) && 333 if (bus->number == orion_pci_local_bus_nr() &&
337 (orion_pci_local_dev_nr() == PCI_SLOT(devfn))) { 334 PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) {
338 *val = 0xffffffff; 335 *val = 0xffffffff;
339 return PCIBIOS_DEVICE_NOT_FOUND; 336 return PCIBIOS_DEVICE_NOT_FOUND;
340 } 337 }
@@ -346,11 +343,8 @@ static int orion_pci_rd_conf(struct pci_bus *bus, u32 devfn,
346static int orion_pci_wr_conf(struct pci_bus *bus, u32 devfn, 343static int orion_pci_wr_conf(struct pci_bus *bus, u32 devfn,
347 int where, int size, u32 val) 344 int where, int size, u32 val)
348{ 345{
349 /* 346 if (bus->number == orion_pci_local_bus_nr() &&
350 * Don't go out for local device 347 PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
351 */
352 if ((orion_pci_local_bus_nr() == bus->number) &&
353 (orion_pci_local_dev_nr() == PCI_SLOT(devfn)))
354 return PCIBIOS_DEVICE_NOT_FOUND; 348 return PCIBIOS_DEVICE_NOT_FOUND;
355 349
356 return orion_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn), 350 return orion_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
@@ -389,23 +383,21 @@ static void __init orion_pci_set_bus_nr(int nr)
389 383
390static void __init orion_pci_master_slave_enable(void) 384static void __init orion_pci_master_slave_enable(void)
391{ 385{
392 int bus_nr, dev_nr, func, reg; 386 int bus_nr, func, reg;
393 u32 val; 387 u32 val;
394 388
395 bus_nr = orion_pci_local_bus_nr(); 389 bus_nr = orion_pci_local_bus_nr();
396 dev_nr = orion_pci_local_dev_nr();
397 func = PCI_CONF_FUNC_STAT_CMD; 390 func = PCI_CONF_FUNC_STAT_CMD;
398 reg = PCI_CONF_REG_STAT_CMD; 391 reg = PCI_CONF_REG_STAT_CMD;
399 orion_pci_hw_rd_conf(bus_nr, dev_nr, func, reg, 4, &val); 392 orion_pci_hw_rd_conf(bus_nr, 0, func, reg, 4, &val);
400 val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); 393 val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
401 orion_pci_hw_wr_conf(bus_nr, dev_nr, func, reg, 4, val | 0x7); 394 orion_pci_hw_wr_conf(bus_nr, 0, func, reg, 4, val | 0x7);
402} 395}
403 396
404static void __init orion_setup_pci_wins(struct mbus_dram_target_info *dram) 397static void __init orion_setup_pci_wins(struct mbus_dram_target_info *dram)
405{ 398{
406 u32 win_enable; 399 u32 win_enable;
407 int bus; 400 int bus;
408 int dev;
409 int i; 401 int i;
410 402
411 /* 403 /*
@@ -418,7 +410,6 @@ static void __init orion_setup_pci_wins(struct mbus_dram_target_info *dram)
418 * Setup windows for DDR banks. 410 * Setup windows for DDR banks.
419 */ 411 */
420 bus = orion_pci_local_bus_nr(); 412 bus = orion_pci_local_bus_nr();
421 dev = orion_pci_local_dev_nr();
422 413
423 for (i = 0; i < dram->num_cs; i++) { 414 for (i = 0; i < dram->num_cs; i++) {
424 struct mbus_dram_window *cs = dram->cs + i; 415 struct mbus_dram_window *cs = dram->cs + i;
@@ -430,15 +421,15 @@ static void __init orion_setup_pci_wins(struct mbus_dram_target_info *dram)
430 * Write DRAM bank base address register. 421 * Write DRAM bank base address register.
431 */ 422 */
432 reg = PCI_CONF_REG_BAR_LO_CS(cs->cs_index); 423 reg = PCI_CONF_REG_BAR_LO_CS(cs->cs_index);
433 orion_pci_hw_rd_conf(bus, dev, func, reg, 4, &val); 424 orion_pci_hw_rd_conf(bus, 0, func, reg, 4, &val);
434 val = (cs->base & 0xfffff000) | (val & 0xfff); 425 val = (cs->base & 0xfffff000) | (val & 0xfff);
435 orion_pci_hw_wr_conf(bus, dev, func, reg, 4, val); 426 orion_pci_hw_wr_conf(bus, 0, func, reg, 4, val);
436 427
437 /* 428 /*
438 * Write DRAM bank size register. 429 * Write DRAM bank size register.
439 */ 430 */
440 reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index); 431 reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index);
441 orion_pci_hw_wr_conf(bus, dev, func, reg, 4, 0); 432 orion_pci_hw_wr_conf(bus, 0, func, reg, 4, 0);
442 orion_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index), 433 orion_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index),
443 (cs->size - 1) & 0xfffff000); 434 (cs->size - 1) & 0xfffff000);
444 orion_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index), 435 orion_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index),
@@ -519,6 +510,23 @@ static int __init pci_setup(struct pci_sys_data *sys)
519/***************************************************************************** 510/*****************************************************************************
520 * General PCIE + PCI 511 * General PCIE + PCI
521 ****************************************************************************/ 512 ****************************************************************************/
513static void __devinit rc_pci_fixup(struct pci_dev *dev)
514{
515 /*
516 * Prevent enumeration of root complex.
517 */
518 if (dev->bus->parent == NULL && dev->devfn == 0) {
519 int i;
520
521 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
522 dev->resource[i].start = 0;
523 dev->resource[i].end = 0;
524 dev->resource[i].flags = 0;
525 }
526 }
527}
528DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
529
522int __init orion_pci_sys_setup(int nr, struct pci_sys_data *sys) 530int __init orion_pci_sys_setup(int nr, struct pci_sys_data *sys)
523{ 531{
524 int ret = 0; 532 int ret = 0;