xref: /openbmc/linux/arch/mips/pci/pci-ip32.c (revision 87c2ce3b)
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2000, 2001 Keith M Wesolowski
7  * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8  */
9 #include <linux/config.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/pci.h>
14 #include <linux/types.h>
15 #include <asm/ip32/mace.h>
16 #include <asm/ip32/ip32_ints.h>
17 
18 #undef DEBUG_MACE_PCI
19 
20 /*
21  * Handle errors from the bridge.  This includes master and target aborts,
22  * various command and address errors, and the interrupt test.  This gets
23  * registered on the bridge error irq.  It's conceivable that some of these
24  * conditions warrant a panic.  Anybody care to say which ones?
25  */
26 static irqreturn_t macepci_error(int irq, void *dev, struct pt_regs *regs)
27 {
28 	char s;
29 	unsigned int flags = mace->pci.error;
30 	unsigned int addr = mace->pci.error_addr;
31 
32 	if (flags & MACEPCI_ERROR_MEMORY_ADDR)
33 		s = 'M';
34 	else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
35 		s = 'C';
36 	else
37 		s = 'X';
38 
39 	if (flags & MACEPCI_ERROR_MASTER_ABORT) {
40 		printk("MACEPCI: Master abort at 0x%08x (%c)\n", addr, s);
41 		flags &= ~MACEPCI_ERROR_MASTER_ABORT;
42 	}
43 	if (flags & MACEPCI_ERROR_TARGET_ABORT) {
44 		printk("MACEPCI: Target abort at 0x%08x (%c)\n", addr, s);
45 		flags &= ~MACEPCI_ERROR_TARGET_ABORT;
46 	}
47 	if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
48 		printk("MACEPCI: Data parity error at 0x%08x (%c)\n", addr, s);
49 		flags &= ~MACEPCI_ERROR_DATA_PARITY_ERR;
50 	}
51 	if (flags & MACEPCI_ERROR_RETRY_ERR) {
52 		printk("MACEPCI: Retry error at 0x%08x (%c)\n", addr, s);
53 		flags &= ~MACEPCI_ERROR_RETRY_ERR;
54 	}
55 	if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
56 		printk("MACEPCI: Illegal command at 0x%08x (%c)\n", addr, s);
57 		flags &= ~MACEPCI_ERROR_ILLEGAL_CMD;
58 	}
59 	if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
60 		printk("MACEPCI: System error at 0x%08x (%c)\n", addr, s);
61 		flags &= ~MACEPCI_ERROR_SYSTEM_ERR;
62 	}
63 	if (flags & MACEPCI_ERROR_PARITY_ERR) {
64 		printk("MACEPCI: Parity error at 0x%08x (%c)\n", addr, s);
65 		flags &= ~MACEPCI_ERROR_PARITY_ERR;
66 	}
67 	if (flags & MACEPCI_ERROR_OVERRUN) {
68 		printk("MACEPCI: Overrun error at 0x%08x (%c)\n", addr, s);
69 		flags &= ~MACEPCI_ERROR_OVERRUN;
70 	}
71 	if (flags & MACEPCI_ERROR_SIG_TABORT) {
72 		printk("MACEPCI: Signaled target abort (clearing)\n");
73 		flags &= ~MACEPCI_ERROR_SIG_TABORT;
74 	}
75 	if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
76 		printk("MACEPCI: Interrupt test triggered (clearing)\n");
77 		flags &= ~MACEPCI_ERROR_INTERRUPT_TEST;
78 	}
79 
80 	mace->pci.error = flags;
81 
82 	return IRQ_HANDLED;
83 }
84 
85 
86 extern struct pci_ops mace_pci_ops;
87 #ifdef CONFIG_64BIT
88 static struct resource mace_pci_mem_resource = {
89 	.name	= "SGI O2 PCI MEM",
90 	.start	= MACEPCI_HI_MEMORY,
91 	.end	= 0x2FFFFFFFFUL,
92 	.flags	= IORESOURCE_MEM,
93 };
94 static struct resource mace_pci_io_resource = {
95 	.name	= "SGI O2 PCI IO",
96 	.start	= 0x00000000UL,
97 	.end	= 0xffffffffUL,
98 	.flags	= IORESOURCE_IO,
99 };
100 #define MACE_PCI_MEM_OFFSET 0x200000000
101 #else
102 static struct resource mace_pci_mem_resource = {
103 	.name	= "SGI O2 PCI MEM",
104 	.start	= MACEPCI_LOW_MEMORY,
105 	.end	= MACEPCI_LOW_MEMORY + 0x2000000 - 1,
106 	.flags	= IORESOURCE_MEM,
107 };
108 static struct resource mace_pci_io_resource = {
109 	.name	= "SGI O2 PCI IO",
110 	.start	= 0x00000000,
111 	.end	= 0xFFFFFFFF,
112 	.flags	= IORESOURCE_IO,
113 };
114 #define MACE_PCI_MEM_OFFSET (MACEPCI_LOW_MEMORY - 0x80000000)
115 #endif
116 static struct pci_controller mace_pci_controller = {
117 	.pci_ops	= &mace_pci_ops,
118 	.mem_resource	= &mace_pci_mem_resource,
119 	.io_resource	= &mace_pci_io_resource,
120 	.iommu		= 0,
121 	.mem_offset	= MACE_PCI_MEM_OFFSET,
122 	.io_offset	= 0,
123 };
124 
125 static int __init mace_init(void)
126 {
127 	PCIBIOS_MIN_IO = 0x1000;
128 
129 	/* Clear any outstanding errors and enable interrupts */
130 	mace->pci.error_addr = 0;
131 	mace->pci.error = 0;
132 	mace->pci.control = 0xff008500;
133 
134 	printk("MACE PCI rev %d\n", mace->pci.rev);
135 
136 	BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
137 			   "MACE PCI error", NULL));
138 
139 	iomem_resource = mace_pci_mem_resource;
140 	ioport_resource = mace_pci_io_resource;
141 
142 	register_pci_controller(&mace_pci_controller);
143 
144 	return 0;
145 }
146 
147 arch_initcall(mace_init);
148