aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci/ops-tx4927.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pci/ops-tx4927.c')
-rw-r--r--arch/mips/pci/ops-tx4927.c118
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
21static struct { 23static 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
199char *__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
195void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr, 221void __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
436static 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
460void 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
470irqreturn_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
497static 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
524DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0,
525 tx4927_quirk_slc90e66_bridge);
526#endif