aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pci')
-rw-r--r--arch/mips/pci/ops-tx3927.c80
-rw-r--r--arch/mips/pci/ops-tx4927.c118
-rw-r--r--arch/mips/pci/pci-tx4927.c10
-rw-r--r--arch/mips/pci/pci-tx4938.c10
-rw-r--r--arch/mips/pci/pci.c6
5 files changed, 196 insertions, 28 deletions
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c
index 8a17a39e5bf2..31c150196595 100644
--- a/arch/mips/pci/ops-tx3927.c
+++ b/arch/mips/pci/ops-tx3927.c
@@ -37,45 +37,48 @@
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/interrupt.h>
40 41
41#include <asm/addrspace.h> 42#include <asm/addrspace.h>
43#include <asm/txx9irq.h>
44#include <asm/txx9/pci.h>
42#include <asm/txx9/tx3927.h> 45#include <asm/txx9/tx3927.h>
43 46
44static inline int mkaddr(unsigned char bus, unsigned char dev_fn, 47static int mkaddr(struct pci_bus *bus, unsigned char devfn, unsigned char where)
45 unsigned char where)
46{ 48{
47 if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0)) 49 if (bus->parent == NULL &&
48 return PCIBIOS_DEVICE_NOT_FOUND; 50 devfn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
49 51 return -1;
50 tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) | 52 tx3927_pcicptr->ica =
51 ((dev_fn & 0xff) << 0x08) | 53 ((bus->number & 0xff) << 0x10) |
52 (where & 0xfc); 54 ((devfn & 0xff) << 0x08) |
55 (where & 0xfc) | (bus->parent ? 1 : 0);
53 56
54 /* clear M_ABORT and Disable M_ABORT Int. */ 57 /* clear M_ABORT and Disable M_ABORT Int. */
55 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; 58 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
56 tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT; 59 tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
57 60 return 0;
58 return PCIBIOS_SUCCESSFUL;
59} 61}
60 62
61static inline int check_abort(void) 63static inline int check_abort(void)
62{ 64{
63 if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) 65 if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) {
64 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; 66 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
65 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; 67 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
68 /* flush write buffer */
69 iob();
66 return PCIBIOS_DEVICE_NOT_FOUND; 70 return PCIBIOS_DEVICE_NOT_FOUND;
67 71 }
68 return PCIBIOS_SUCCESSFUL; 72 return PCIBIOS_SUCCESSFUL;
69} 73}
70 74
71static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, 75static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
72 int where, int size, u32 * val) 76 int where, int size, u32 * val)
73{ 77{
74 int ret; 78 if (mkaddr(bus, devfn, where)) {
75 79 *val = 0xffffffff;
76 ret = mkaddr(bus->number, devfn, where); 80 return PCIBIOS_DEVICE_NOT_FOUND;
77 if (ret) 81 }
78 return ret;
79 82
80 switch (size) { 83 switch (size) {
81 case 1: 84 case 1:
@@ -97,11 +100,8 @@ static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
97static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, 100static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
98 int where, int size, u32 val) 101 int where, int size, u32 val)
99{ 102{
100 int ret; 103 if (mkaddr(bus, devfn, where))
101 104 return PCIBIOS_DEVICE_NOT_FOUND;
102 ret = mkaddr(bus->number, devfn, where);
103 if (ret)
104 return ret;
105 105
106 switch (size) { 106 switch (size) {
107 case 1: 107 case 1:
@@ -117,11 +117,6 @@ static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
117 tx3927_pcicptr->icd = cpu_to_le32(val); 117 tx3927_pcicptr->icd = cpu_to_le32(val);
118 } 118 }
119 119
120 if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
121 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
122 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
123 return PCIBIOS_DEVICE_NOT_FOUND;
124
125 return check_abort(); 120 return check_abort();
126} 121}
127 122
@@ -202,3 +197,34 @@ void __init tx3927_pcic_setup(struct pci_controller *channel,
202 PCI_COMMAND_PARITY | PCI_COMMAND_SERR; 197 PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
203 local_irq_restore(flags); 198 local_irq_restore(flags);
204} 199}
200
201static irqreturn_t tx3927_pcierr_interrupt(int irq, void *dev_id)
202{
203 struct pt_regs *regs = get_irq_regs();
204
205 if (txx9_pci_err_action != TXX9_PCI_ERR_IGNORE) {
206 printk(KERN_WARNING "PCI error interrupt at 0x%08lx.\n",
207 regs->cp0_epc);
208 printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
209 tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
210 }
211 if (txx9_pci_err_action != TXX9_PCI_ERR_PANIC) {
212 /* clear all pci errors */
213 tx3927_pcicptr->pcistat |= TX3927_PCIC_PCISTATIM_ALL;
214 tx3927_pcicptr->istat = TX3927_PCIC_IIM_ALL;
215 tx3927_pcicptr->tstat = TX3927_PCIC_TIM_ALL;
216 tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
217 return IRQ_HANDLED;
218 }
219 console_verbose();
220 panic("PCI error.");
221}
222
223void __init tx3927_setup_pcierr_irq(void)
224{
225 if (request_irq(TXX9_IRQ_BASE + TX3927_IR_PCI,
226 tx3927_pcierr_interrupt,
227 IRQF_DISABLED, "PCI error",
228 (void *)TX3927_PCIC_REG))
229 printk(KERN_WARNING "Failed to request irq for PCIERR\n");
230}
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
diff --git a/arch/mips/pci/pci-tx4927.c b/arch/mips/pci/pci-tx4927.c
index 27e86a09dd41..aaa900596792 100644
--- a/arch/mips/pci/pci-tx4927.c
+++ b/arch/mips/pci/pci-tx4927.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/pci.h> 16#include <linux/pci.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/interrupt.h>
18#include <asm/txx9/generic.h> 19#include <asm/txx9/generic.h>
19#include <asm/txx9/tx4927.h> 20#include <asm/txx9/tx4927.h>
20 21
@@ -81,3 +82,12 @@ int __init tx4927_pciclk66_setup(void)
81 pciclk = -1; 82 pciclk = -1;
82 return pciclk; 83 return pciclk;
83} 84}
85
86void __init tx4927_setup_pcierr_irq(void)
87{
88 if (request_irq(TXX9_IRQ_BASE + TX4927_IR_PCIERR,
89 tx4927_pcierr_interrupt,
90 IRQF_DISABLED, "PCI error",
91 (void *)TX4927_PCIC_REG))
92 printk(KERN_WARNING "Failed to request irq for PCIERR\n");
93}
diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c
index e5375511c2b7..60e2c52c2c5e 100644
--- a/arch/mips/pci/pci-tx4938.c
+++ b/arch/mips/pci/pci-tx4938.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/pci.h> 16#include <linux/pci.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/interrupt.h>
18#include <asm/txx9/generic.h> 19#include <asm/txx9/generic.h>
19#include <asm/txx9/tx4938.h> 20#include <asm/txx9/tx4938.h>
20 21
@@ -132,3 +133,12 @@ int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot)
132 } 133 }
133 return -1; 134 return -1;
134} 135}
136
137void __init tx4938_setup_pcierr_irq(void)
138{
139 if (request_irq(TXX9_IRQ_BASE + TX4938_IR_PCIERR,
140 tx4927_pcierr_interrupt,
141 IRQF_DISABLED, "PCI error",
142 (void *)TX4927_PCIC_REG))
143 printk(KERN_WARNING "Failed to request irq for PCIERR\n");
144}
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 77bd5b68dc43..c7fe6ec621e6 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -328,7 +328,11 @@ EXPORT_SYMBOL(PCIBIOS_MIN_IO);
328EXPORT_SYMBOL(PCIBIOS_MIN_MEM); 328EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
329#endif 329#endif
330 330
331char *pcibios_setup(char *str) 331char * (*pcibios_plat_setup)(char *str) __devinitdata;
332
333char *__devinit pcibios_setup(char *str)
332{ 334{
335 if (pcibios_plat_setup)
336 return pcibios_plat_setup(str);
333 return str; 337 return str;
334} 338}