aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pci')
-rw-r--r--arch/mips/pci/fixup-au1000.c43
-rw-r--r--arch/mips/pci/fixup-yosemite.c41
-rw-r--r--arch/mips/pci/ops-au1000.c308
-rw-r--r--arch/mips/pci/ops-titan-ht.c124
-rw-r--r--arch/mips/pci/ops-titan.c111
-rw-r--r--arch/mips/pci/pci-yosemite.c67
6 files changed, 694 insertions, 0 deletions
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
new file mode 100644
index 00000000000..e2ddfc49237
--- /dev/null
+++ b/arch/mips/pci/fixup-au1000.c
@@ -0,0 +1,43 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Board specific PCI fixups.
4 *
5 * Copyright 2001-2003, 2008 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc. <source@mvista.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/pci.h>
30#include <linux/init.h>
31
32extern char irq_tab_alchemy[][5];
33
34int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
35{
36 return irq_tab_alchemy[slot][pin];
37}
38
39/* Do platform specific device initialization at pci_enable_device() time */
40int pcibios_plat_dev_init(struct pci_dev *dev)
41{
42 return 0;
43}
diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c
new file mode 100644
index 00000000000..fdafb13a793
--- /dev/null
+++ b/arch/mips/pci/fixup-yosemite.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2003 PMC-Sierra
3 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/pci.h>
28
29int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
30{
31 if (pin == 0)
32 return -1;
33
34 return 3; /* Everything goes to one irq bit */
35}
36
37/* Do platform specific device initialization at pci_enable_device() time */
38int pcibios_plat_dev_init(struct pci_dev *dev)
39{
40 return 0;
41}
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
new file mode 100644
index 00000000000..9a57c5ab91d
--- /dev/null
+++ b/arch/mips/pci/ops-au1000.c
@@ -0,0 +1,308 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Alchemy/AMD Au1xx0 PCI support.
4 *
5 * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc. <source@mvista.com>
7 *
8 * Support for all devices (greater than 16) added by David Gathright.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/types.h>
32#include <linux/pci.h>
33#include <linux/kernel.h>
34#include <linux/init.h>
35#include <linux/vmalloc.h>
36
37#include <asm/mach-au1x00/au1000.h>
38
39#undef DEBUG
40#ifdef DEBUG
41#define DBG(x...) printk(KERN_DEBUG x)
42#else
43#define DBG(x...)
44#endif
45
46#define PCI_ACCESS_READ 0
47#define PCI_ACCESS_WRITE 1
48
49int (*board_pci_idsel)(unsigned int devsel, int assert);
50
51void mod_wired_entry(int entry, unsigned long entrylo0,
52 unsigned long entrylo1, unsigned long entryhi,
53 unsigned long pagemask)
54{
55 unsigned long old_pagemask;
56 unsigned long old_ctx;
57
58 /* Save old context and create impossible VPN2 value */
59 old_ctx = read_c0_entryhi() & 0xff;
60 old_pagemask = read_c0_pagemask();
61 write_c0_index(entry);
62 write_c0_pagemask(pagemask);
63 write_c0_entryhi(entryhi);
64 write_c0_entrylo0(entrylo0);
65 write_c0_entrylo1(entrylo1);
66 tlb_write_indexed();
67 write_c0_entryhi(old_ctx);
68 write_c0_pagemask(old_pagemask);
69}
70
71static struct vm_struct *pci_cfg_vm;
72static int pci_cfg_wired_entry;
73static unsigned long last_entryLo0, last_entryLo1;
74
75/*
76 * We can't ioremap the entire pci config space because it's too large.
77 * Nor can we call ioremap dynamically because some device drivers use
78 * the PCI config routines from within interrupt handlers and that
79 * becomes a problem in get_vm_area(). We use one wired TLB to handle
80 * all config accesses for all busses.
81 */
82void __init au1x_pci_cfg_init(void)
83{
84 /* Reserve a wired entry for PCI config accesses */
85 pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP);
86 if (!pci_cfg_vm)
87 panic(KERN_ERR "PCI unable to get vm area\n");
88 pci_cfg_wired_entry = read_c0_wired();
89 add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K);
90 last_entryLo0 = last_entryLo1 = 0xffffffff;
91}
92
93static int config_access(unsigned char access_type, struct pci_bus *bus,
94 unsigned int dev_fn, unsigned char where, u32 *data)
95{
96#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
97 unsigned int device = PCI_SLOT(dev_fn);
98 unsigned int function = PCI_FUNC(dev_fn);
99 unsigned long offset, status;
100 unsigned long cfg_base;
101 unsigned long flags;
102 int error = PCIBIOS_SUCCESSFUL;
103 unsigned long entryLo0, entryLo1;
104
105 if (device > 19) {
106 *data = 0xffffffff;
107 return -1;
108 }
109
110 local_irq_save(flags);
111 au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
112 Au1500_PCI_STATCMD);
113 au_sync_udelay(1);
114
115 /*
116 * Allow board vendors to implement their own off-chip IDSEL.
117 * If it doesn't succeed, may as well bail out at this point.
118 */
119 if (board_pci_idsel && board_pci_idsel(device, 1) == 0) {
120 *data = 0xffffffff;
121 local_irq_restore(flags);
122 return -1;
123 }
124
125 /* Setup the config window */
126 if (bus->number == 0)
127 cfg_base = (1 << device) << 11;
128 else
129 cfg_base = 0x80000000 | (bus->number << 16) | (device << 11);
130
131 /* Setup the lower bits of the 36-bit address */
132 offset = (function << 8) | (where & ~0x3);
133 /* Pick up any address that falls below the page mask */
134 offset |= cfg_base & ~PAGE_MASK;
135
136 /* Page boundary */
137 cfg_base = cfg_base & PAGE_MASK;
138
139 /*
140 * To improve performance, if the current device is the same as
141 * the last device accessed, we don't touch the TLB.
142 */
143 entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
144 entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
145 if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
146 mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
147 (unsigned long)pci_cfg_vm->addr, PM_4K);
148 last_entryLo0 = entryLo0;
149 last_entryLo1 = entryLo1;
150 }
151
152 if (access_type == PCI_ACCESS_WRITE)
153 au_writel(*data, (int)(pci_cfg_vm->addr + offset));
154 else
155 *data = au_readl((int)(pci_cfg_vm->addr + offset));
156
157 au_sync_udelay(2);
158
159 DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n",
160 access_type, bus->number, device, where, *data, offset);
161
162 /* Check master abort */
163 status = au_readl(Au1500_PCI_STATCMD);
164
165 if (status & (1 << 29)) {
166 *data = 0xffffffff;
167 error = -1;
168 DBG("Au1x Master Abort\n");
169 } else if ((status >> 28) & 0xf) {
170 DBG("PCI ERR detected: device %u, status %lx\n",
171 device, (status >> 28) & 0xf);
172
173 /* Clear errors */
174 au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD);
175
176 *data = 0xffffffff;
177 error = -1;
178 }
179
180 /* Take away the IDSEL. */
181 if (board_pci_idsel)
182 (void)board_pci_idsel(device, 0);
183
184 local_irq_restore(flags);
185 return error;
186#endif
187}
188
189static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
190 int where, u8 *val)
191{
192 u32 data;
193 int ret;
194
195 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
196 if (where & 1)
197 data >>= 8;
198 if (where & 2)
199 data >>= 16;
200 *val = data & 0xff;
201 return ret;
202}
203
204static int read_config_word(struct pci_bus *bus, unsigned int devfn,
205 int where, u16 *val)
206{
207 u32 data;
208 int ret;
209
210 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
211 if (where & 2)
212 data >>= 16;
213 *val = data & 0xffff;
214 return ret;
215}
216
217static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
218 int where, u32 *val)
219{
220 int ret;
221
222 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
223 return ret;
224}
225
226static int write_config_byte(struct pci_bus *bus, unsigned int devfn,
227 int where, u8 val)
228{
229 u32 data = 0;
230
231 if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
232 return -1;
233
234 data = (data & ~(0xff << ((where & 3) << 3))) |
235 (val << ((where & 3) << 3));
236
237 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
238 return -1;
239
240 return PCIBIOS_SUCCESSFUL;
241}
242
243static int write_config_word(struct pci_bus *bus, unsigned int devfn,
244 int where, u16 val)
245{
246 u32 data = 0;
247
248 if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
249 return -1;
250
251 data = (data & ~(0xffff << ((where & 3) << 3))) |
252 (val << ((where & 3) << 3));
253
254 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
255 return -1;
256
257 return PCIBIOS_SUCCESSFUL;
258}
259
260static int write_config_dword(struct pci_bus *bus, unsigned int devfn,
261 int where, u32 val)
262{
263 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
264 return -1;
265
266 return PCIBIOS_SUCCESSFUL;
267}
268
269static int config_read(struct pci_bus *bus, unsigned int devfn,
270 int where, int size, u32 *val)
271{
272 switch (size) {
273 case 1: {
274 u8 _val;
275 int rc = read_config_byte(bus, devfn, where, &_val);
276
277 *val = _val;
278 return rc;
279 }
280 case 2: {
281 u16 _val;
282 int rc = read_config_word(bus, devfn, where, &_val);
283
284 *val = _val;
285 return rc;
286 }
287 default:
288 return read_config_dword(bus, devfn, where, val);
289 }
290}
291
292static int config_write(struct pci_bus *bus, unsigned int devfn,
293 int where, int size, u32 val)
294{
295 switch (size) {
296 case 1:
297 return write_config_byte(bus, devfn, where, (u8) val);
298 case 2:
299 return write_config_word(bus, devfn, where, (u16) val);
300 default:
301 return write_config_dword(bus, devfn, where, val);
302 }
303}
304
305struct pci_ops au1x_pci_ops = {
306 config_read,
307 config_write
308};
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
new file mode 100644
index 00000000000..57d54adc9e2
--- /dev/null
+++ b/arch/mips/pci/ops-titan-ht.c
@@ -0,0 +1,124 @@
1/*
2 * Copyright 2003 PMC-Sierra
3 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/types.h>
27#include <linux/pci.h>
28#include <linux/kernel.h>
29#include <linux/delay.h>
30#include <asm/io.h>
31
32#include <asm/titan_dep.h>
33
34static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
35 int offset, u32 *val)
36{
37 volatile uint32_t address;
38 int busno;
39
40 busno = bus->number;
41
42 address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
43 if (busno != 0)
44 address |= 1;
45
46 /*
47 * RM9000 HT Errata: Issue back to back HT config
48 * transcations. Issue a BIU sync before and
49 * after the HT cycle
50 */
51
52 *(volatile int32_t *) 0xfb0000f0 |= 0x2;
53
54 udelay(30);
55
56 *(volatile int32_t *) 0xfb0006f8 = address;
57 *(val) = *(volatile int32_t *) 0xfb0006fc;
58
59 udelay(30);
60
61 * (volatile int32_t *) 0xfb0000f0 |= 0x2;
62
63 return PCIBIOS_SUCCESSFUL;
64}
65
66static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn,
67 int offset, int size, u32 *val)
68{
69 uint32_t dword;
70
71 titan_ht_config_read_dword(bus, devfn, offset, &dword);
72
73 dword >>= ((offset & 3) << 3);
74 dword &= (0xffffffffU >> ((4 - size) << 8));
75
76 return PCIBIOS_SUCCESSFUL;
77}
78
79static inline int titan_ht_config_write_dword(struct pci_bus *bus,
80 unsigned int devfn, int offset, u32 val)
81{
82 volatile uint32_t address;
83 int busno;
84
85 busno = bus->number;
86
87 address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
88 if (busno != 0)
89 address |= 1;
90
91 *(volatile int32_t *) 0xfb0000f0 |= 0x2;
92
93 udelay(30);
94
95 *(volatile int32_t *) 0xfb0006f8 = address;
96 *(volatile int32_t *) 0xfb0006fc = val;
97
98 udelay(30);
99
100 *(volatile int32_t *) 0xfb0000f0 |= 0x2;
101
102 return PCIBIOS_SUCCESSFUL;
103}
104
105static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn,
106 int offset, int size, u32 val)
107{
108 uint32_t val1, val2, mask;
109
110 titan_ht_config_read_dword(bus, devfn, offset, &val2);
111
112 val1 = val << ((offset & 3) << 3);
113 mask = ~(0xffffffffU >> ((4 - size) << 8));
114 val2 &= ~(mask << ((offset & 3) << 8));
115
116 titan_ht_config_write_dword(bus, devfn, offset, val1 | val2);
117
118 return PCIBIOS_SUCCESSFUL;
119}
120
121struct pci_ops titan_ht_pci_ops = {
122 .read = titan_ht_config_read,
123 .write = titan_ht_config_write,
124};
diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c
new file mode 100644
index 00000000000..ebf8fc40e9b
--- /dev/null
+++ b/arch/mips/pci/ops-titan.c
@@ -0,0 +1,111 @@
1/*
2 * Copyright 2003 PMC-Sierra
3 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25#include <linux/types.h>
26#include <linux/pci.h>
27#include <linux/kernel.h>
28
29#include <asm/pci.h>
30#include <asm/io.h>
31#include <asm/rm9k-ocd.h>
32
33/*
34 * PCI specific defines
35 */
36#define TITAN_PCI_0_CONFIG_ADDRESS 0x780
37#define TITAN_PCI_0_CONFIG_DATA 0x784
38
39/*
40 * Titan PCI Config Read Byte
41 */
42static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
43 int size, u32 * val)
44{
45 uint32_t address, tmp;
46 int dev, busno, func;
47
48 busno = bus->number;
49 dev = PCI_SLOT(devfn);
50 func = PCI_FUNC(devfn);
51
52 address = (busno << 16) | (dev << 11) | (func << 8) |
53 (reg & 0xfc) | 0x80000000;
54
55
56 /* start the configuration cycle */
57 ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS);
58 tmp = ocd_readl(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
59
60 switch (size) {
61 case 1:
62 tmp &= 0xff;
63 case 2:
64 tmp &= 0xffff;
65 }
66 *val = tmp;
67
68 return PCIBIOS_SUCCESSFUL;
69}
70
71static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
72 int size, u32 val)
73{
74 uint32_t address;
75 int dev, busno, func;
76
77 busno = bus->number;
78 dev = PCI_SLOT(devfn);
79 func = PCI_FUNC(devfn);
80
81 address = (busno << 16) | (dev << 11) | (func << 8) |
82 (reg & 0xfc) | 0x80000000;
83
84 /* start the configuration cycle */
85 ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS);
86
87 /* write the data */
88 switch (size) {
89 case 1:
90 ocd_writeb(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3));
91 break;
92
93 case 2:
94 ocd_writew(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2));
95 break;
96
97 case 4:
98 ocd_writel(val, TITAN_PCI_0_CONFIG_DATA);
99 break;
100 }
101
102 return PCIBIOS_SUCCESSFUL;
103}
104
105/*
106 * Titan PCI structure
107 */
108struct pci_ops titan_pci_ops = {
109 titan_read_config,
110 titan_write_config,
111};
diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c
new file mode 100644
index 00000000000..cf5e1a25cb7
--- /dev/null
+++ b/arch/mips/pci/pci-yosemite.c
@@ -0,0 +1,67 @@
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) 2004 by Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/types.h>
11#include <linux/pci.h>
12#include <asm/titan_dep.h>
13
14extern struct pci_ops titan_pci_ops;
15
16static struct resource py_mem_resource = {
17 .start = 0xe0000000UL,
18 .end = 0xe3ffffffUL,
19 .name = "Titan PCI MEM",
20 .flags = IORESOURCE_MEM
21};
22
23/*
24 * PMON really reserves 16MB of I/O port space but that's stupid, nothing
25 * needs that much since allocations are limited to 256 bytes per device
26 * anyway. So we just claim 64kB here.
27 */
28#define TITAN_IO_SIZE 0x0000ffffUL
29#define TITAN_IO_BASE 0xe8000000UL
30
31static struct resource py_io_resource = {
32 .start = 0x00001000UL,
33 .end = TITAN_IO_SIZE - 1,
34 .name = "Titan IO MEM",
35 .flags = IORESOURCE_IO,
36};
37
38static struct pci_controller py_controller = {
39 .pci_ops = &titan_pci_ops,
40 .mem_resource = &py_mem_resource,
41 .mem_offset = 0x00000000UL,
42 .io_resource = &py_io_resource,
43 .io_offset = 0x00000000UL
44};
45
46static char ioremap_failed[] __initdata = "Could not ioremap I/O port range";
47
48static int __init pmc_yosemite_setup(void)
49{
50 unsigned long io_v_base;
51
52 io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
53 if (!io_v_base)
54 panic(ioremap_failed);
55
56 set_io_port_base(io_v_base);
57 py_controller.io_map_base = io_v_base;
58 TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
59
60 ioport_resource.end = TITAN_IO_SIZE - 1;
61
62 register_pci_controller(&py_controller);
63
64 return 0;
65}
66
67arch_initcall(pmc_yosemite_setup);