aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-orion5x/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-orion5x/pci.c')
-rw-r--r--arch/arm/mach-orion5x/pci.c86
1 files changed, 55 insertions, 31 deletions
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index 9d5d39fa19c3..256a4f680935 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -152,6 +152,8 @@ static int __init pcie_setup(struct pci_sys_data *sys)
152 if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { 152 if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
153 printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config " 153 printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
154 "read transaction workaround\n"); 154 "read transaction workaround\n");
155 orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
156 ORION5X_PCIE_WA_SIZE);
155 pcie_ops.read = pcie_rd_conf_wa; 157 pcie_ops.read = pcie_rd_conf_wa;
156 } 158 }
157 159
@@ -240,13 +242,13 @@ static int __init pcie_setup(struct pci_sys_data *sys)
240 * PCI Address Decode Windows registers 242 * PCI Address Decode Windows registers
241 */ 243 */
242#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \ 244#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \
243 ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \ 245 ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
244 ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \ 246 ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
245 ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0) 247 ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0)
246#define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION5X_PCI_REG(0xc48) : \ 248#define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \
247 ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \ 249 ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
248 ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \ 250 ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
249 ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0) 251 ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0)
250#define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c) 252#define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c)
251#define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c) 253#define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c)
252 254
@@ -264,9 +266,11 @@ static int __init pcie_setup(struct pci_sys_data *sys)
264 */ 266 */
265static DEFINE_SPINLOCK(orion5x_pci_lock); 267static DEFINE_SPINLOCK(orion5x_pci_lock);
266 268
269static int orion5x_pci_cardbus_mode;
270
267static int orion5x_pci_local_bus_nr(void) 271static int orion5x_pci_local_bus_nr(void)
268{ 272{
269 u32 conf = orion5x_read(PCI_P2P_CONF); 273 u32 conf = readl(PCI_P2P_CONF);
270 return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); 274 return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
271} 275}
272 276
@@ -276,11 +280,11 @@ static int orion5x_pci_hw_rd_conf(int bus, int dev, u32 func,
276 unsigned long flags; 280 unsigned long flags;
277 spin_lock_irqsave(&orion5x_pci_lock, flags); 281 spin_lock_irqsave(&orion5x_pci_lock, flags);
278 282
279 orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | 283 writel(PCI_CONF_BUS(bus) |
280 PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | 284 PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
281 PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); 285 PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
282 286
283 *val = orion5x_read(PCI_CONF_DATA); 287 *val = readl(PCI_CONF_DATA);
284 288
285 if (size == 1) 289 if (size == 1)
286 *val = (*val >> (8*(where & 0x3))) & 0xff; 290 *val = (*val >> (8*(where & 0x3))) & 0xff;
@@ -300,9 +304,9 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func,
300 304
301 spin_lock_irqsave(&orion5x_pci_lock, flags); 305 spin_lock_irqsave(&orion5x_pci_lock, flags);
302 306
303 orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) | 307 writel(PCI_CONF_BUS(bus) |
304 PCI_CONF_DEV(dev) | PCI_CONF_REG(where) | 308 PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
305 PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN); 309 PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
306 310
307 if (size == 4) { 311 if (size == 4) {
308 __raw_writel(val, PCI_CONF_DATA); 312 __raw_writel(val, PCI_CONF_DATA);
@@ -319,14 +323,30 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func,
319 return ret; 323 return ret;
320} 324}
321 325
326static int orion5x_pci_valid_config(int bus, u32 devfn)
327{
328 if (bus == orion5x_pci_local_bus_nr()) {
329 /*
330 * Don't go out for local device
331 */
332 if (PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
333 return 0;
334
335 /*
336 * When the PCI signals are directly connected to a
337 * Cardbus slot, ignore all but device IDs 0 and 1.
338 */
339 if (orion5x_pci_cardbus_mode && PCI_SLOT(devfn) > 1)
340 return 0;
341 }
342
343 return 1;
344}
345
322static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn, 346static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
323 int where, int size, u32 *val) 347 int where, int size, u32 *val)
324{ 348{
325 /* 349 if (!orion5x_pci_valid_config(bus->number, devfn)) {
326 * Don't go out for local device
327 */
328 if (bus->number == orion5x_pci_local_bus_nr() &&
329 PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) {
330 *val = 0xffffffff; 350 *val = 0xffffffff;
331 return PCIBIOS_DEVICE_NOT_FOUND; 351 return PCIBIOS_DEVICE_NOT_FOUND;
332 } 352 }
@@ -338,8 +358,7 @@ static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
338static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn, 358static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn,
339 int where, int size, u32 val) 359 int where, int size, u32 val)
340{ 360{
341 if (bus->number == orion5x_pci_local_bus_nr() && 361 if (!orion5x_pci_valid_config(bus->number, devfn))
342 PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
343 return PCIBIOS_DEVICE_NOT_FOUND; 362 return PCIBIOS_DEVICE_NOT_FOUND;
344 363
345 return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn), 364 return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
@@ -353,9 +372,9 @@ static struct pci_ops pci_ops = {
353 372
354static void __init orion5x_pci_set_bus_nr(int nr) 373static void __init orion5x_pci_set_bus_nr(int nr)
355{ 374{
356 u32 p2p = orion5x_read(PCI_P2P_CONF); 375 u32 p2p = readl(PCI_P2P_CONF);
357 376
358 if (orion5x_read(PCI_MODE) & PCI_MODE_PCIX) { 377 if (readl(PCI_MODE) & PCI_MODE_PCIX) {
359 /* 378 /*
360 * PCI-X mode 379 * PCI-X mode
361 */ 380 */
@@ -372,7 +391,7 @@ static void __init orion5x_pci_set_bus_nr(int nr)
372 */ 391 */
373 p2p &= ~PCI_P2P_BUS_MASK; 392 p2p &= ~PCI_P2P_BUS_MASK;
374 p2p |= (nr << PCI_P2P_BUS_OFFS); 393 p2p |= (nr << PCI_P2P_BUS_OFFS);
375 orion5x_write(PCI_P2P_CONF, p2p); 394 writel(p2p, PCI_P2P_CONF);
376 } 395 }
377} 396}
378 397
@@ -399,7 +418,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
399 * First, disable windows. 418 * First, disable windows.
400 */ 419 */
401 win_enable = 0xffffffff; 420 win_enable = 0xffffffff;
402 orion5x_write(PCI_BAR_ENABLE, win_enable); 421 writel(win_enable, PCI_BAR_ENABLE);
403 422
404 /* 423 /*
405 * Setup windows for DDR banks. 424 * Setup windows for DDR banks.
@@ -425,10 +444,10 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
425 */ 444 */
426 reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index); 445 reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index);
427 orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0); 446 orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0);
428 orion5x_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index), 447 writel((cs->size - 1) & 0xfffff000,
429 (cs->size - 1) & 0xfffff000); 448 PCI_BAR_SIZE_DDR_CS(cs->cs_index));
430 orion5x_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index), 449 writel(cs->base & 0xfffff000,
431 cs->base & 0xfffff000); 450 PCI_BAR_REMAP_DDR_CS(cs->cs_index));
432 451
433 /* 452 /*
434 * Enable decode window for this chip select. 453 * Enable decode window for this chip select.
@@ -439,7 +458,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
439 /* 458 /*
440 * Re-enable decode windows. 459 * Re-enable decode windows.
441 */ 460 */
442 orion5x_write(PCI_BAR_ENABLE, win_enable); 461 writel(win_enable, PCI_BAR_ENABLE);
443 462
444 /* 463 /*
445 * Disable automatic update of address remaping when writing to BARs. 464 * Disable automatic update of address remaping when writing to BARs.
@@ -522,6 +541,11 @@ static void __devinit rc_pci_fixup(struct pci_dev *dev)
522} 541}
523DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup); 542DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
524 543
544void __init orion5x_pci_set_cardbus_mode(void)
545{
546 orion5x_pci_cardbus_mode = 1;
547}
548
525int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys) 549int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)
526{ 550{
527 int ret = 0; 551 int ret = 0;