diff options
Diffstat (limited to 'arch/mips/pci/ops-tx4927.c')
-rw-r--r-- | arch/mips/pci/ops-tx4927.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index c6b49bccd274..5989e747527f 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * option) any later version. | 16 | * option) any later version. |
17 | */ | 17 | */ |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/interrupt.h> | ||
20 | #include <asm/txx9/pci.h> | ||
19 | #include <asm/txx9/tx4927pcic.h> | 21 | #include <asm/txx9/tx4927pcic.h> |
20 | 22 | ||
21 | static struct { | 23 | static struct { |
@@ -85,6 +87,8 @@ static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr) | |||
85 | __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) | 87 | __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) |
86 | | (PCI_STATUS_REC_MASTER_ABORT << 16), | 88 | | (PCI_STATUS_REC_MASTER_ABORT << 16), |
87 | &pcicptr->pcistatus); | 89 | &pcicptr->pcistatus); |
90 | /* flush write buffer */ | ||
91 | iob(); | ||
88 | code = PCIBIOS_DEVICE_NOT_FOUND; | 92 | code = PCIBIOS_DEVICE_NOT_FOUND; |
89 | } | 93 | } |
90 | return code; | 94 | return code; |
@@ -192,6 +196,28 @@ static struct { | |||
192 | .gbwc = 0xfe0, /* 4064 GBUSCLK for CCFG.GTOT=0b11 */ | 196 | .gbwc = 0xfe0, /* 4064 GBUSCLK for CCFG.GTOT=0b11 */ |
193 | }; | 197 | }; |
194 | 198 | ||
199 | char *__devinit tx4927_pcibios_setup(char *str) | ||
200 | { | ||
201 | unsigned long val; | ||
202 | |||
203 | if (!strncmp(str, "trdyto=", 7)) { | ||
204 | if (strict_strtoul(str + 7, 0, &val) == 0) | ||
205 | tx4927_pci_opts.trdyto = val; | ||
206 | return NULL; | ||
207 | } | ||
208 | if (!strncmp(str, "retryto=", 8)) { | ||
209 | if (strict_strtoul(str + 8, 0, &val) == 0) | ||
210 | tx4927_pci_opts.retryto = val; | ||
211 | return NULL; | ||
212 | } | ||
213 | if (!strncmp(str, "gbwc=", 5)) { | ||
214 | if (strict_strtoul(str + 5, 0, &val) == 0) | ||
215 | tx4927_pci_opts.gbwc = val; | ||
216 | return NULL; | ||
217 | } | ||
218 | return str; | ||
219 | } | ||
220 | |||
195 | void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr, | 221 | void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr, |
196 | struct pci_controller *channel, int extarb) | 222 | struct pci_controller *channel, int extarb) |
197 | { | 223 | { |
@@ -406,3 +432,95 @@ void tx4927_report_pcic_status(void) | |||
406 | tx4927_report_pcic_status1(pcicptrs[i].pcicptr); | 432 | tx4927_report_pcic_status1(pcicptrs[i].pcicptr); |
407 | } | 433 | } |
408 | } | 434 | } |
435 | |||
436 | static void tx4927_dump_pcic_settings1(struct tx4927_pcic_reg __iomem *pcicptr) | ||
437 | { | ||
438 | int i; | ||
439 | __u32 __iomem *preg = (__u32 __iomem *)pcicptr; | ||
440 | |||
441 | printk(KERN_INFO "tx4927 pcic (0x%p) settings:", pcicptr); | ||
442 | for (i = 0; i < sizeof(struct tx4927_pcic_reg); i += 4, preg++) { | ||
443 | if (i % 32 == 0) { | ||
444 | printk(KERN_CONT "\n"); | ||
445 | printk(KERN_INFO "%04x:", i); | ||
446 | } | ||
447 | /* skip registers with side-effects */ | ||
448 | if (i == offsetof(struct tx4927_pcic_reg, g2pintack) | ||
449 | || i == offsetof(struct tx4927_pcic_reg, g2pspc) | ||
450 | || i == offsetof(struct tx4927_pcic_reg, g2pcfgadrs) | ||
451 | || i == offsetof(struct tx4927_pcic_reg, g2pcfgdata)) { | ||
452 | printk(KERN_CONT " XXXXXXXX"); | ||
453 | continue; | ||
454 | } | ||
455 | printk(KERN_CONT " %08x", __raw_readl(preg)); | ||
456 | } | ||
457 | printk(KERN_CONT "\n"); | ||
458 | } | ||
459 | |||
460 | void tx4927_dump_pcic_settings(void) | ||
461 | { | ||
462 | int i; | ||
463 | |||
464 | for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { | ||
465 | if (pcicptrs[i].pcicptr) | ||
466 | tx4927_dump_pcic_settings1(pcicptrs[i].pcicptr); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id) | ||
471 | { | ||
472 | struct pt_regs *regs = get_irq_regs(); | ||
473 | struct tx4927_pcic_reg __iomem *pcicptr = | ||
474 | (struct tx4927_pcic_reg __iomem *)(unsigned long)dev_id; | ||
475 | |||
476 | if (txx9_pci_err_action != TXX9_PCI_ERR_IGNORE) { | ||
477 | printk(KERN_WARNING "PCIERR interrupt at 0x%0*lx\n", | ||
478 | (int)(2 * sizeof(unsigned long)), regs->cp0_epc); | ||
479 | tx4927_report_pcic_status1(pcicptr); | ||
480 | } | ||
481 | if (txx9_pci_err_action != TXX9_PCI_ERR_PANIC) { | ||
482 | /* clear all pci errors */ | ||
483 | __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) | ||
484 | | (TX4927_PCIC_PCISTATUS_ALL << 16), | ||
485 | &pcicptr->pcistatus); | ||
486 | __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pstatus); | ||
487 | __raw_writel(TX4927_PCIC_PBASTATUS_ALL, &pcicptr->pbastatus); | ||
488 | __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicstatus); | ||
489 | return IRQ_HANDLED; | ||
490 | } | ||
491 | console_verbose(); | ||
492 | tx4927_dump_pcic_settings1(pcicptr); | ||
493 | panic("PCI error."); | ||
494 | } | ||
495 | |||
496 | #ifdef CONFIG_TOSHIBA_FPCIB0 | ||
497 | static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) | ||
498 | { | ||
499 | struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus); | ||
500 | |||
501 | if (!pcicptr) | ||
502 | return; | ||
503 | if (__raw_readl(&pcicptr->pbacfg) & TX4927_PCIC_PBACFG_PBAEN) { | ||
504 | /* Reset Bus Arbiter */ | ||
505 | __raw_writel(TX4927_PCIC_PBACFG_RPBA, &pcicptr->pbacfg); | ||
506 | /* | ||
507 | * swap reqBP and reqXP (raise priority of SLC90E66). | ||
508 | * SLC90E66(PCI-ISA bridge) is connected to REQ2 on | ||
509 | * PCI Backplane board. | ||
510 | */ | ||
511 | __raw_writel(0x72543610, &pcicptr->pbareqport); | ||
512 | __raw_writel(0, &pcicptr->pbabm); | ||
513 | /* Use Fixed ParkMaster (required by SLC90E66) */ | ||
514 | __raw_writel(TX4927_PCIC_PBACFG_FIXPA, &pcicptr->pbacfg); | ||
515 | /* Enable Bus Arbiter */ | ||
516 | __raw_writel(TX4927_PCIC_PBACFG_FIXPA | | ||
517 | TX4927_PCIC_PBACFG_PBAEN, | ||
518 | &pcicptr->pbacfg); | ||
519 | printk(KERN_INFO "PCI: Use Fixed Park Master (REQPORT %08x)\n", | ||
520 | __raw_readl(&pcicptr->pbareqport)); | ||
521 | } | ||
522 | } | ||
523 | #define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 | ||
524 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0, | ||
525 | tx4927_quirk_slc90e66_bridge); | ||
526 | #endif | ||