aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/pci
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/mips/pci')
-rw-r--r--arch/mips/pci/Makefile54
-rw-r--r--arch/mips/pci/fixup-atlas.c69
-rw-r--r--arch/mips/pci/fixup-au1000.c123
-rw-r--r--arch/mips/pci/fixup-capcella.c50
-rw-r--r--arch/mips/pci/fixup-cobalt.c112
-rw-r--r--arch/mips/pci/fixup-ddb5074.c21
-rw-r--r--arch/mips/pci/fixup-ddb5477.c78
-rw-r--r--arch/mips/pci/fixup-ev64120.c34
-rw-r--r--arch/mips/pci/fixup-ev96100.c48
-rw-r--r--arch/mips/pci/fixup-ip32.c51
-rw-r--r--arch/mips/pci/fixup-ite8172g.c80
-rw-r--r--arch/mips/pci/fixup-ivr.c75
-rw-r--r--arch/mips/pci/fixup-jaguar.c43
-rw-r--r--arch/mips/pci/fixup-jmr3927.c105
-rw-r--r--arch/mips/pci/fixup-malta.c103
-rw-r--r--arch/mips/pci/fixup-mpc30x.c50
-rw-r--r--arch/mips/pci/fixup-ocelot-c.c41
-rw-r--r--arch/mips/pci/fixup-ocelot-g.c37
-rw-r--r--arch/mips/pci/fixup-ocelot.c75
-rw-r--r--arch/mips/pci/fixup-ocelot3.c41
-rw-r--r--arch/mips/pci/fixup-rbtx4927.c140
-rw-r--r--arch/mips/pci/fixup-sb1250.c24
-rw-r--r--arch/mips/pci/fixup-sni.c89
-rw-r--r--arch/mips/pci/fixup-tb0219.c66
-rw-r--r--arch/mips/pci/fixup-tb0226.c85
-rw-r--r--arch/mips/pci/fixup-vr4133.c204
-rw-r--r--arch/mips/pci/fixup-yosemite.c41
-rw-r--r--arch/mips/pci/ops-au1000.c325
-rw-r--r--arch/mips/pci/ops-bonito64.c196
-rw-r--r--arch/mips/pci/ops-ddb5074.c271
-rw-r--r--arch/mips/pci/ops-ddb5476.c286
-rw-r--r--arch/mips/pci/ops-ddb5477.c278
-rw-r--r--arch/mips/pci/ops-gt64111.c100
-rw-r--r--arch/mips/pci/ops-gt64120.c154
-rw-r--r--arch/mips/pci/ops-gt96100.c169
-rw-r--r--arch/mips/pci/ops-it8172.c215
-rw-r--r--arch/mips/pci/ops-mace.c91
-rw-r--r--arch/mips/pci/ops-marvell.c93
-rw-r--r--arch/mips/pci/ops-msc.c169
-rw-r--r--arch/mips/pci/ops-nile4.c147
-rw-r--r--arch/mips/pci/ops-sni.c89
-rw-r--r--arch/mips/pci/ops-titan-ht.c125
-rw-r--r--arch/mips/pci/ops-titan.c100
-rw-r--r--arch/mips/pci/ops-tx3927.c391
-rw-r--r--arch/mips/pci/ops-tx4927.c209
-rw-r--r--arch/mips/pci/ops-vr41xx.c126
-rw-r--r--arch/mips/pci/pci-ddb5074.c79
-rw-r--r--arch/mips/pci/pci-ddb5476.c93
-rw-r--r--arch/mips/pci/pci-ddb5477.c207
-rw-r--r--arch/mips/pci/pci-ev96100.c63
-rw-r--r--arch/mips/pci/pci-ip27.c489
-rw-r--r--arch/mips/pci/pci-ip32.c145
-rw-r--r--arch/mips/pci/pci-jmr3927.c58
-rw-r--r--arch/mips/pci/pci-lasat.c95
-rw-r--r--arch/mips/pci/pci-ocelot-c.c143
-rw-r--r--arch/mips/pci/pci-ocelot-g.c97
-rw-r--r--arch/mips/pci/pci-ocelot.c107
-rw-r--r--arch/mips/pci/pci-sb1250.c292
-rw-r--r--arch/mips/pci/pci-vr41xx.c291
-rw-r--r--arch/mips/pci/pci-vr41xx.h151
-rw-r--r--arch/mips/pci/pci-yosemite.c60
-rw-r--r--arch/mips/pci/pci.c304
62 files changed, 8147 insertions, 0 deletions
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
new file mode 100644
index 00000000000..c53e4cb359b
--- /dev/null
+++ b/arch/mips/pci/Makefile
@@ -0,0 +1,54 @@
1#
2# Makefile for the PCI specific kernel interface routines under Linux.
3#
4
5obj-y += pci.o
6
7#
8# PCI bus host bridge specific code
9#
10obj-$(CONFIG_ITE_BOARD_GEN) += ops-it8172.o
11obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o
12obj-$(CONFIG_MIPS_GT64111) += ops-gt64111.o
13obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o
14obj-$(CONFIG_MIPS_GT96100) += ops-gt96100.o
15obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o
16obj-$(CONFIG_MIPS_MSC) += ops-msc.o
17obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
18obj-$(CONFIG_MIPS_TX3927) += ops-jmr3927.o
19obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o
20obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o
21
22#
23# These are still pretty much in the old state, watch, go blind.
24#
25obj-$(CONFIG_DDB5074) += fixup-ddb5074.o pci-ddb5074.o ops-ddb5074.o
26obj-$(CONFIG_DDB5476) += ops-ddb5476.o pci-ddb5476.o
27obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o
28obj-$(CONFIG_LASAT) += pci-lasat.o
29obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o
30obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
31obj-$(CONFIG_MIPS_EV96100) += fixup-ev64120.o
32obj-$(CONFIG_MIPS_EV96100) += fixup-ev96100.o pci-ev96100.o
33obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o
34obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o
35obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
36obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
37obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o
38obj-$(CONFIG_MOMENCO_JAGUAR_ATX)+= fixup-jaguar.o
39obj-$(CONFIG_MOMENCO_OCELOT) += fixup-ocelot.o pci-ocelot.o
40obj-$(CONFIG_MOMENCO_OCELOT_3) += fixup-ocelot3.o
41obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o
42obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o pci-ocelot-g.o
43obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
44 pci-yosemite.o
45obj-$(CONFIG_SGI_IP27) += pci-ip27.o
46obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o
47obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
48obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o
49obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
50obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
51obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o
52obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o
53obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
54obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
new file mode 100644
index 00000000000..2406835833d
--- /dev/null
+++ b/arch/mips/pci/fixup-atlas.c
@@ -0,0 +1,69 @@
1#include <linux/config.h>
2#include <linux/init.h>
3#include <linux/pci.h>
4#include <asm/mips-boards/atlasint.h>
5
6#define INTD ATLASINT_INTD
7#define INTC ATLASINT_INTC
8#define INTB ATLASINT_INTB
9#define INTA ATLASINT_INTA
10#define SCSI ATLASINT_SCSI
11#define ETH ATLASINT_ETH
12
13static char irq_tab[][5] __initdata = {
14 /* INTA INTB INTC INTD */
15 {0, 0, 0, 0, 0 }, /* 0: Unused */
16 {0, 0, 0, 0, 0 }, /* 1: Unused */
17 {0, 0, 0, 0, 0 }, /* 2: Unused */
18 {0, 0, 0, 0, 0 }, /* 3: Unused */
19 {0, 0, 0, 0, 0 }, /* 4: Unused */
20 {0, 0, 0, 0, 0 }, /* 5: Unused */
21 {0, 0, 0, 0, 0 }, /* 6: Unused */
22 {0, 0, 0, 0, 0 }, /* 7: Unused */
23 {0, 0, 0, 0, 0 }, /* 8: Unused */
24 {0, 0, 0, 0, 0 }, /* 9: Unused */
25 {0, 0, 0, 0, 0 }, /* 10: Unused */
26 {0, 0, 0, 0, 0 }, /* 11: Unused */
27 {0, 0, 0, 0, 0 }, /* 12: Unused */
28 {0, 0, 0, 0, 0 }, /* 13: Unused */
29 {0, 0, 0, 0, 0 }, /* 14: Unused */
30 {0, 0, 0, 0, 0 }, /* 15: Unused */
31 {0, SCSI, 0, 0, 0 }, /* 16: SYM53C810A SCSI */
32 {0, 0, 0, 0, 0 }, /* 17: Core */
33 {0, INTA, INTB, INTC, INTD }, /* 18: PCI Slot 1 */
34 {0, ETH, 0, 0, 0 }, /* 19: SAA9730 Ethernet */
35 {0, 0, 0, 0, 0 }, /* 20: PCI Slot 3 */
36 {0, 0, 0, 0, 0 } /* 21: PCI Slot 4 */
37};
38
39int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
40{
41 return irq_tab[slot][pin];
42}
43
44/* Do platform specific device initialization at pci_enable_device() time */
45int pcibios_plat_dev_init(struct pci_dev *dev)
46{
47 return 0;
48}
49
50#ifdef CONFIG_KGDB
51/*
52 * The PCI scan may have moved the saa9730 I/O address, so reread
53 * the address here.
54 * This does mean that it's not possible to debug the PCI bus configuration
55 * code, but it is better than nothing...
56 */
57
58static void atlas_saa9730_base_fixup (struct pci_dev *pdev)
59{
60 extern void *saa9730_base;
61 if (pdev->bus == 0 && PCI_SLOT(pdev->devfn) == 19)
62 (void) pci_read_config_dword (pdev, 0x14, (u32 *)&saa9730_base);
63 printk ("saa9730_base = %x\n", saa9730_base);
64}
65
66DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9730,
67 atlas_saa9730_base_fixup);
68
69#endif
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
new file mode 100644
index 00000000000..39fe2b16fce
--- /dev/null
+++ b/arch/mips/pci/fixup-au1000.c
@@ -0,0 +1,123 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Board specific pci fixups.
4 *
5 * Copyright 2001-2003 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29#include <linux/config.h>
30#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/kernel.h>
33#include <linux/init.h>
34
35#include <asm/mach-au1x00/au1000.h>
36
37/*
38 * Shortcut
39 */
40#ifdef CONFIG_SOC_AU1500
41#define INTA AU1000_PCI_INTA
42#define INTB AU1000_PCI_INTB
43#define INTC AU1000_PCI_INTC
44#define INTD AU1000_PCI_INTD
45#endif
46
47#ifdef CONFIG_SOC_AU1550
48#define INTA AU1550_PCI_INTA
49#define INTB AU1550_PCI_INTB
50#define INTC AU1550_PCI_INTC
51#define INTD AU1550_PCI_INTD
52#endif
53
54#define INTX 0xFF /* not valid */
55
56#ifdef CONFIG_MIPS_DB1500
57static char irq_tab_alchemy[][5] __initdata = {
58 [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT371 */
59 [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
60};
61#endif
62
63#ifdef CONFIG_MIPS_BOSPORUS
64static char irq_tab_alchemy[][5] __initdata = {
65 [11] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 11 - miniPCI */
66 [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - SN1741 */
67 [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
68};
69#endif
70
71#ifdef CONFIG_MIPS_MIRAGE
72static char irq_tab_alchemy[][5] __initdata = {
73 [11] = { -1, INTD, INTX, INTX, INTX}, /* IDSEL 11 - SMI VGX */
74 [12] = { -1, INTX, INTX, INTC, INTX}, /* IDSEL 12 - PNX1300 */
75 [13] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 13 - miniPCI */
76};
77#endif
78
79#ifdef CONFIG_MIPS_DB1550
80static char irq_tab_alchemy[][5] __initdata = {
81 [11] = { -1, INTC, INTX, INTX, INTX}, /* IDSEL 11 - on-board HPT371 */
82 [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
83 [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
84};
85#endif
86
87#ifdef CONFIG_MIPS_PB1500
88static char irq_tab_alchemy[][5] __initdata = {
89 [12] = { -1, INTA, INTX, INTX, INTX}, /* IDSEL 12 - HPT370 */
90 [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot */
91};
92#endif
93
94#ifdef CONFIG_MIPS_PB1550
95static char irq_tab_alchemy[][5] __initdata = {
96 [12] = { -1, INTB, INTC, INTD, INTA}, /* IDSEL 12 - PCI slot 2 (left) */
97 [13] = { -1, INTA, INTB, INTC, INTD}, /* IDSEL 13 - PCI slot 1 (right) */
98};
99#endif
100
101#ifdef CONFIG_MIPS_MTX1
102static char irq_tab_alchemy[][5] __initdata = {
103 [0] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */
104 [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
105 [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */
106 [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
107 [4] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 04 - AdapterC-Slot0 (top) */
108 [5] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
109 [6] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 06 - AdapterD-Slot0 (top) */
110 [7] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
111};
112#endif
113
114int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
115{
116 return irq_tab_alchemy[slot][pin];
117}
118
119/* Do platform specific device initialization at pci_enable_device() time */
120int pcibios_plat_dev_init(struct pci_dev *dev)
121{
122 return 0;
123}
diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c
new file mode 100644
index 00000000000..f2fc82c1c7c
--- /dev/null
+++ b/arch/mips/pci/fixup-capcella.c
@@ -0,0 +1,50 @@
1/*
2 * fixup-cappcela.c, The ZAO Networks Capcella specific PCI fixups.
3 *
4 * Copyright (C) 2002,2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <linux/init.h>
21#include <linux/pci.h>
22
23#include <asm/vr41xx/capcella.h>
24
25/*
26 * Shortcuts
27 */
28#define INT1 RTL8139_1_IRQ
29#define INT2 RTL8139_2_IRQ
30#define INTA PC104PLUS_INTA_IRQ
31#define INTB PC104PLUS_INTB_IRQ
32#define INTC PC104PLUS_INTC_IRQ
33#define INTD PC104PLUS_INTD_IRQ
34
35static char irq_tab_capcella[][5] __initdata = {
36 [11] = { -1, INT1, INT1, INT1, INT1 },
37 [12] = { -1, INT2, INT2, INT2, INT2 },
38 [14] = { -1, INTA, INTB, INTC, INTD }
39};
40
41int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
42{
43 return irq_tab_capcella[slot][pin];
44}
45
46/* Do platform specific device initialization at pci_enable_device() time */
47int pcibios_plat_dev_init(struct pci_dev *dev)
48{
49 return 0;
50}
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
new file mode 100644
index 00000000000..57e1ca2116b
--- /dev/null
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -0,0 +1,112 @@
1/*
2 * Cobalt Qube/Raq PCI support
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1995, 1996, 1997, 2002, 2003 by Ralf Baechle
9 * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
10 */
11#include <linux/types.h>
12#include <linux/pci.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15
16#include <asm/pci.h>
17#include <asm/io.h>
18#include <asm/gt64120.h>
19
20#include <asm/cobalt/cobalt.h>
21
22extern int cobalt_board_id;
23
24static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
25{
26 unsigned short cfgword;
27 unsigned char lt;
28
29 /* Enable Bus Mastering and fast back to back. */
30 pci_read_config_word(dev, PCI_COMMAND, &cfgword);
31 cfgword |= (PCI_COMMAND_FAST_BACK | PCI_COMMAND_MASTER);
32 pci_write_config_word(dev, PCI_COMMAND, cfgword);
33
34 /* Enable both ide interfaces. ROM only enables primary one. */
35 pci_write_config_byte(dev, 0x40, 0xb);
36
37 /* Set latency timer to reasonable value. */
38 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lt);
39 if (lt < 64)
40 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
41 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
42}
43
44DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
45 qube_raq_via_bmIDE_fixup);
46
47static void qube_raq_galileo_fixup(struct pci_dev *dev)
48{
49 unsigned short galileo_id;
50
51 /* Fix PCI latency-timer and cache-line-size values in Galileo
52 * host bridge.
53 */
54 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
55 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
56
57 /*
58 * On all machines prior to Q2, we had the STOP line disconnected
59 * from Galileo to VIA on PCI. The new Galileo does not function
60 * correctly unless we have it connected.
61 *
62 * Therefore we must set the disconnect/retry cycle values to
63 * something sensible when using the new Galileo.
64 */
65 pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
66 galileo_id &= 0xff; /* mask off class info */
67 if (galileo_id >= 0x10) {
68 /* New Galileo, assumes PCI stop line to VIA is connected. */
69 GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS);
70 } else if (galileo_id == 0x1 || galileo_id == 0x2) {
71 signed int timeo;
72 /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
73 timeo = GALILEO_INL(GT_PCI0_TOR_OFS);
74 /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
75 GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS);
76 }
77}
78
79DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GALILEO, PCI_ANY_ID,
80 qube_raq_galileo_fixup);
81
82static char irq_tab_cobalt[] __initdata = {
83 [COBALT_PCICONF_CPU] = 0,
84 [COBALT_PCICONF_ETH0] = COBALT_ETH0_IRQ,
85 [COBALT_PCICONF_RAQSCSI] = COBALT_SCSI_IRQ,
86 [COBALT_PCICONF_VIA] = 0,
87 [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
88 [COBALT_PCICONF_ETH1] = COBALT_ETH1_IRQ
89};
90
91static char irq_tab_raq2[] __initdata = {
92 [COBALT_PCICONF_CPU] = 0,
93 [COBALT_PCICONF_ETH0] = COBALT_ETH0_IRQ,
94 [COBALT_PCICONF_RAQSCSI] = COBALT_RAQ_SCSI_IRQ,
95 [COBALT_PCICONF_VIA] = 0,
96 [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
97 [COBALT_PCICONF_ETH1] = COBALT_ETH1_IRQ
98};
99
100int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
101{
102 if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
103 return irq_tab_raq2[slot];
104
105 return irq_tab_cobalt[slot];
106}
107
108/* Do platform specific device initialization at pci_enable_device() time */
109int pcibios_plat_dev_init(struct pci_dev *dev)
110{
111 return 0;
112}
diff --git a/arch/mips/pci/fixup-ddb5074.c b/arch/mips/pci/fixup-ddb5074.c
new file mode 100644
index 00000000000..b345e528a53
--- /dev/null
+++ b/arch/mips/pci/fixup-ddb5074.c
@@ -0,0 +1,21 @@
1/*
2 * It's nice to have the LEDs on the GPIO pins available for debugging
3 */
4static void ddb5074_fixup(struct pci_dev *dev)
5{
6 extern struct pci_dev *pci_pmu;
7 u8 t8;
8
9 pci_pmu = dev; /* for LEDs D2 and D3 */
10 /* Program the lines for LEDs D2 and D3 to output */
11 pci_read_config_byte(dev, 0x7d, &t8);
12 t8 |= 0xc0;
13 pci_write_config_byte(dev, 0x7d, t8);
14 /* Turn LEDs D2 and D3 off */
15 pci_read_config_byte(dev, 0x7e, &t8);
16 t8 |= 0xc0;
17 pci_write_config_byte(dev, 0x7e, t8);
18}
19
20DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
21 ddb5074_fixup);
diff --git a/arch/mips/pci/fixup-ddb5477.c b/arch/mips/pci/fixup-ddb5477.c
new file mode 100644
index 00000000000..6abdc88bab1
--- /dev/null
+++ b/arch/mips/pci/fixup-ddb5477.c
@@ -0,0 +1,78 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * Board specific pci fixups.
5 *
6 * Copyright 2001, 2002, 2003 MontaVista Software Inc.
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/kernel.h>
33#include <linux/init.h>
34
35static void ddb5477_fixup(struct pci_dev *dev)
36{
37 u8 old;
38
39 printk(KERN_NOTICE "Enabling ALI M1533/35 PS2 keyboard/mouse.\n");
40 pci_read_config_byte(dev, 0x41, &old);
41 pci_write_config_byte(dev, 0x41, old | 0xd0);
42}
43
44DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
45 ddb5477_fixup);
46DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1535,
47 ddb5477_fixup);
48
49/*
50 * Fixup baseboard AMD chip so that tx does not underflow.
51 * bcr_18 |= 0x0800
52 * This sets NOUFLO bit which makes tx not start until whole pkt
53 * is fetched to the chip.
54 */
55#define PCNET32_WIO_RDP 0x10
56#define PCNET32_WIO_RAP 0x12
57#define PCNET32_WIO_RESET 0x14
58#define PCNET32_WIO_BDP 0x16
59
60static void ddb5477_amd_lance_fixup(struct pci_dev *dev)
61{
62 unsigned long ioaddr;
63 u16 temp;
64
65 ioaddr = pci_resource_start(dev, 0);
66
67 inw(ioaddr + PCNET32_WIO_RESET); /* reset chip */
68
69 /* bcr_18 |= 0x0800 */
70 outw(18, ioaddr + PCNET32_WIO_RAP);
71 temp = inw(ioaddr + PCNET32_WIO_BDP);
72 temp |= 0x0800;
73 outw(18, ioaddr + PCNET32_WIO_RAP);
74 outw(temp, ioaddr + PCNET32_WIO_BDP);
75}
76
77DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
78 ddb5477_amd_lance_fixup);
diff --git a/arch/mips/pci/fixup-ev64120.c b/arch/mips/pci/fixup-ev64120.c
new file mode 100644
index 00000000000..8dbb90d63f0
--- /dev/null
+++ b/arch/mips/pci/fixup-ev64120.c
@@ -0,0 +1,34 @@
1#include <linux/pci.h>
2#include <linux/init.h>
3
4int pci_range_ck(unsigned char bus, unsigned char dev)
5{
6 if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8))
7 return 0;
8
9 return -1;
10}
11
12/*
13 * After detecting all agents over the PCI , this function is called
14 * in order to give an interrupt number for each PCI device starting
15 * from IRQ 20. It does also enables master for each device.
16 */
17void __devinit pcibios_fixup_bus(struct pci_bus *bus)
18{
19 unsigned int irq = 20;
20 struct pci_bus *current_bus = bus;
21 struct pci_dev *dev;
22 struct list_head *devices_link;
23
24 list_for_each(devices_link, &(current_bus->devices)) {
25 dev = pci_dev_b(devices_link);
26 if (dev != NULL) {
27 dev->irq = irq++;
28
29 /* Assign an interrupt number for the device */
30 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
31 pcibios_set_master(dev);
32 }
33 }
34}
diff --git a/arch/mips/pci/fixup-ev96100.c b/arch/mips/pci/fixup-ev96100.c
new file mode 100644
index 00000000000..e2bc977b6d5
--- /dev/null
+++ b/arch/mips/pci/fixup-ev96100.c
@@ -0,0 +1,48 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * EV96100 Board specific pci fixups.
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
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#include <linux/init.h>
31#include <linux/types.h>
32#include <linux/pci.h>
33
34static char irq_tab_ev96100[][5] __initdata = {
35 [8] = { 0, 5, 5, 5, 5 },
36 [9] = { 0, 2, 2, 2, 2 }
37};
38
39int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
40{
41 return irq_tab_ev96100[slot][pin];
42}
43
44/* Do platform specific device initialization at pci_enable_device() time */
45int pcibios_plat_dev_init(struct pci_dev *dev)
46{
47 return 0;
48}
diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c
new file mode 100644
index 00000000000..3e66b0aa63c
--- /dev/null
+++ b/arch/mips/pci/fixup-ip32.c
@@ -0,0 +1,51 @@
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/pci.h>
4#include <asm/ip32/ip32_ints.h>
5/*
6 * O2 has up to 5 PCI devices connected into the MACE bridge. The device
7 * map looks like this:
8 *
9 * 0 aic7xxx 0
10 * 1 aic7xxx 1
11 * 2 expansion slot
12 * 3 N/C
13 * 4 N/C
14 */
15
16#define SCSI0 MACEPCI_SCSI0_IRQ
17#define SCSI1 MACEPCI_SCSI1_IRQ
18#define INTA0 MACEPCI_SLOT0_IRQ
19#define INTA1 MACEPCI_SLOT1_IRQ
20#define INTA2 MACEPCI_SLOT2_IRQ
21#define INTB MACEPCI_SHARED0_IRQ
22#define INTC MACEPCI_SHARED1_IRQ
23#define INTD MACEPCI_SHARED2_IRQ
24static char irq_tab_mace[][5] __initdata = {
25 /* Dummy INT#A INT#B INT#C INT#D */
26 {0, 0, 0, 0, 0}, /* This is placeholder row - never used */
27 {0, SCSI0, SCSI0, SCSI0, SCSI0},
28 {0, SCSI1, SCSI1, SCSI1, SCSI1},
29 {0, INTA0, INTB, INTC, INTD},
30 {0, INTA1, INTC, INTD, INTB},
31 {0, INTA2, INTD, INTB, INTC},
32};
33
34
35/*
36 * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
37 * the device (1-4 => A-D), tell what irq to use. Note that we don't
38 * in theory have slots 4 and 5, and we never normally use the shared
39 * irqs. I suppose a device without a pin A will thank us for doing it
40 * right if there exists such a broken piece of crap.
41 */
42int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
43{
44 return irq_tab_mace[slot][pin];
45}
46
47/* Do platform specific device initialization at pci_enable_device() time */
48int pcibios_plat_dev_init(struct pci_dev *dev)
49{
50 return 0;
51}
diff --git a/arch/mips/pci/fixup-ite8172g.c b/arch/mips/pci/fixup-ite8172g.c
new file mode 100644
index 00000000000..2290ea4228d
--- /dev/null
+++ b/arch/mips/pci/fixup-ite8172g.c
@@ -0,0 +1,80 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Board specific pci fixups.
4 *
5 * Copyright 2000 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29#include <linux/types.h>
30#include <linux/pci.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33
34#include <asm/it8172/it8172.h>
35#include <asm/it8172/it8172_pci.h>
36#include <asm/it8172/it8172_int.h>
37
38/*
39 * Shortcuts
40 */
41#define INTA IT8172_PCI_INTA_IRQ
42#define INTB IT8172_PCI_INTB_IRQ
43#define INTC IT8172_PCI_INTC_IRQ
44#define INTD IT8172_PCI_INTD_IRQ
45
46static const int internal_func_irqs[7] __initdata = {
47 IT8172_AC97_IRQ,
48 IT8172_DMA_IRQ,
49 IT8172_CDMA_IRQ,
50 IT8172_USB_IRQ,
51 IT8172_BRIDGE_MASTER_IRQ,
52 IT8172_IDE_IRQ,
53 IT8172_MC68K_IRQ
54};
55
56static char irq_tab_ite8172g[][5] __initdata = {
57 [0x10] = { 0, INTA, INTB, INTC, INTD },
58 [0x11] = { 0, INTA, INTB, INTC, INTD },
59 [0x12] = { 0, INTB, INTC, INTD, INTA },
60 [0x13] = { 0, INTC, INTD, INTA, INTB },
61 [0x14] = { 0, INTD, INTA, INTB, INTC },
62};
63
64int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
65{
66 /*
67 * Internal device 1 is actually 7 different internal devices on the
68 * IT8172G (a multifunction device).
69 */
70 if (slot == 1)
71 return internal_func_irqs[PCI_FUNC(dev->devfn)];
72
73 return irq_tab_ite8172g[slot][pin];
74}
75
76/* Do platform specific device initialization at pci_enable_device() time */
77int pcibios_plat_dev_init(struct pci_dev *dev)
78{
79 return 0;
80}
diff --git a/arch/mips/pci/fixup-ivr.c b/arch/mips/pci/fixup-ivr.c
new file mode 100644
index 00000000000..0c7c16464c1
--- /dev/null
+++ b/arch/mips/pci/fixup-ivr.c
@@ -0,0 +1,75 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * Globespan IVR board-specific pci fixups.
5 *
6 * Copyright 2000 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
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#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/kernel.h>
33#include <linux/init.h>
34
35#include <asm/it8172/it8172.h>
36#include <asm/it8172/it8172_pci.h>
37#include <asm/it8172/it8172_int.h>
38
39/*
40 * Shortcuts
41 */
42#define INTA IT8172_PCI_INTA_IRQ
43#define INTB IT8172_PCI_INTB_IRQ
44#define INTC IT8172_PCI_INTC_IRQ
45#define INTD IT8172_PCI_INTD_IRQ
46
47static const int internal_func_irqs[7] __initdata = {
48 IT8172_AC97_IRQ,
49 IT8172_DMA_IRQ,
50 IT8172_CDMA_IRQ,
51 IT8172_USB_IRQ,
52 IT8172_BRIDGE_MASTER_IRQ,
53 IT8172_IDE_IRQ,
54 IT8172_MC68K_IRQ
55};
56
57static char irq_tab_ivr[][5] __initdata = {
58 [0x11] = { INTC, INTC, INTD, INTA, INTB }, /* Realtek RTL-8139 */
59 [0x12] = { INTB, INTB, INTB, INTC, INTC }, /* IVR slot */
60 [0x13] = { INTA, INTA, INTB, INTC, INTD } /* Expansion slot */
61};
62
63int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
64{
65 if (slot == 1)
66 return internal_func_irqs[PCI_FUNC(dev->devfn)];
67
68 return irq_tab_ivr[slot][pin];
69}
70
71/* Do platform specific device initialization at pci_enable_device() time */
72int pcibios_plat_dev_init(struct pci_dev *dev)
73{
74 return 0;
75}
diff --git a/arch/mips/pci/fixup-jaguar.c b/arch/mips/pci/fixup-jaguar.c
new file mode 100644
index 00000000000..6c5e1d47179
--- /dev/null
+++ b/arch/mips/pci/fixup-jaguar.c
@@ -0,0 +1,43 @@
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 * Marvell MV64340 interrupt fixup code.
7 *
8 * Marvell wants an NDA for their docs so this was written without
9 * documentation. You've been warned.
10 *
11 * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
12 */
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/pci.h>
16
17#include <asm/mipsregs.h>
18
19/*
20 * WARNING: Example of how _NOT_ to do it.
21 */
22int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
23{
24 int bus = dev->bus->number;
25
26 if (bus == 0 && slot == 1)
27 return 3; /* PCI-X A */
28 if (bus == 0 && slot == 2)
29 return 4; /* PCI-X B */
30 if (bus == 1 && slot == 1)
31 return 5; /* PCI A */
32 if (bus == 1 && slot == 2)
33 return 6; /* PCI B */
34
35return 0;
36 panic("Whooops in pcibios_map_irq");
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-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c
new file mode 100644
index 00000000000..f8696081c5b
--- /dev/null
+++ b/arch/mips/pci/fixup-jmr3927.c
@@ -0,0 +1,105 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * Board specific pci fixups.
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
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#include <linux/types.h>
31#include <linux/pci.h>
32#include <linux/kernel.h>
33#include <linux/init.h>
34
35#include <asm/jmr3927/jmr3927.h>
36
37int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
38{
39 unsigned char irq = pin;
40
41 /* IRQ rotation (PICMG) */
42 irq--; /* 0-3 */
43 if (dev->bus->parent == NULL &&
44 slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) {
45 /* PCI CardSlot (IDSEL=A23, DevNu=12) */
46 /* PCIA => PCIC (IDSEL=A23) */
47 /* NOTE: JMR3927 JP1 must be set to OPEN */
48 irq = (irq + 2) % 4;
49 } else if (dev->bus->parent == NULL &&
50 slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) {
51 /* PCI CardSlot (IDSEL=A22, DevNu=11) */
52 /* PCIA => PCIA (IDSEL=A22) */
53 /* NOTE: JMR3927 JP1 must be set to OPEN */
54 irq = (irq + 0) % 4;
55 } else {
56 /* PCI Backplane */
57 irq = (irq + 3 + slot) % 4;
58 }
59 irq++; /* 1-4 */
60
61 switch (irq) {
62 case 1:
63 irq = JMR3927_IRQ_IOC_PCIA;
64 break;
65 case 2:
66 // wrong for backplane irq = JMR3927_IRQ_IOC_PCIB;
67 irq = JMR3927_IRQ_IOC_PCID;
68 break;
69 case 3:
70 irq = JMR3927_IRQ_IOC_PCIC;
71 break;
72 case 4:
73 // wrong for backplane irq = JMR3927_IRQ_IOC_PCID;
74 irq = JMR3927_IRQ_IOC_PCIB;
75 break;
76 }
77
78 /* Check OnBoard Ethernet (IDSEL=A24, DevNu=13) */
79 if (dev->bus->parent == NULL &&
80 slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(24)) {
81 extern int jmr3927_ether1_irq;
82 /* check this irq line was reserved for ether1 */
83 if (jmr3927_ether1_irq != JMR3927_IRQ_ETHER0)
84 irq = JMR3927_IRQ_ETHER0;
85 else
86 irq = 0; /* disable */
87 }
88 return irq;
89}
90
91/* Do platform specific device initialization at pci_enable_device() time */
92int pcibios_plat_dev_init(struct pci_dev *dev)
93{
94 return 0;
95}
96
97int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
98{
99 /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */
100 if (!(dev->vendor == PCI_VENDOR_ID_EFAR &&
101 dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1))
102 return pci_get_irq(dev, pin);
103
104 dev->irq = irq;
105}
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c
new file mode 100644
index 00000000000..b9296d9942b
--- /dev/null
+++ b/arch/mips/pci/fixup-malta.c
@@ -0,0 +1,103 @@
1#include <linux/init.h>
2#include <linux/pci.h>
3
4/* PCI interrupt pins */
5#define PCIA 1
6#define PCIB 2
7#define PCIC 3
8#define PCID 4
9
10/* This table is filled in by interrogating the PIIX4 chip */
11static char pci_irq[5] __initdata;
12
13static char irq_tab[][5] __initdata = {
14 /* INTA INTB INTC INTD */
15 {0, 0, 0, 0, 0 }, /* 0: GT64120 PCI bridge */
16 {0, 0, 0, 0, 0 }, /* 1: Unused */
17 {0, 0, 0, 0, 0 }, /* 2: Unused */
18 {0, 0, 0, 0, 0 }, /* 3: Unused */
19 {0, 0, 0, 0, 0 }, /* 4: Unused */
20 {0, 0, 0, 0, 0 }, /* 5: Unused */
21 {0, 0, 0, 0, 0 }, /* 6: Unused */
22 {0, 0, 0, 0, 0 }, /* 7: Unused */
23 {0, 0, 0, 0, 0 }, /* 8: Unused */
24 {0, 0, 0, 0, 0 }, /* 9: Unused */
25 {0, 0, 0, 0, PCID }, /* 10: PIIX4 USB */
26 {0, PCIB, 0, 0, 0 }, /* 11: AMD 79C973 Ethernet */
27 {0, PCIC, 0, 0, 0 }, /* 12: Crystal 4281 Sound */
28 {0, 0, 0, 0, 0 }, /* 13: Unused */
29 {0, 0, 0, 0, 0 }, /* 14: Unused */
30 {0, 0, 0, 0, 0 }, /* 15: Unused */
31 {0, 0, 0, 0, 0 }, /* 16: Unused */
32 {0, 0, 0, 0, 0 }, /* 17: Bonito/SOC-it PCI Bridge*/
33 {0, PCIA, PCIB, PCIC, PCID }, /* 18: PCI Slot 1 */
34 {0, PCIB, PCIC, PCID, PCIA }, /* 19: PCI Slot 2 */
35 {0, PCIC, PCID, PCIA, PCIB }, /* 20: PCI Slot 3 */
36 {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */
37};
38
39int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
40{
41 int virq;
42 virq = irq_tab[slot][pin];
43 return pci_irq[virq];
44}
45
46/* Do platform specific device initialization at pci_enable_device() time */
47int pcibios_plat_dev_init(struct pci_dev *dev)
48{
49 return 0;
50}
51
52static void __init malta_piix_func0_fixup(struct pci_dev *pdev)
53{
54 unsigned char reg_val;
55 static int piixirqmap[16] __initdata = { /* PIIX PIRQC[A:D] irq mappings */
56 0, 0, 0, 3,
57 4, 5, 6, 7,
58 0, 9, 10, 11,
59 12, 0, 14, 15
60 };
61 int i;
62
63 /* Interrogate PIIX4 to get PCI IRQ mapping */
64 for (i = 0; i <= 3; i++) {
65 pci_read_config_byte(pdev, 0x60+i, &reg_val);
66 if (reg_val & 0x80)
67 pci_irq[PCIA+i] = 0; /* Disabled */
68 else
69 pci_irq[PCIA+i] = piixirqmap[reg_val & 15];
70 }
71
72 /* Done by YAMON 2.00 onwards */
73 if (PCI_SLOT(pdev->devfn) == 10) {
74 /*
75 * Set top of main memory accessible by ISA or DMA
76 * devices to 16 Mb.
77 */
78 pci_read_config_byte(pdev, 0x69, &reg_val);
79 pci_write_config_byte(pdev, 0x69, reg_val | 0xf0);
80 }
81}
82
83DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
84 malta_piix_func0_fixup);
85
86static void __init malta_piix_func1_fixup(struct pci_dev *pdev)
87{
88 unsigned char reg_val;
89
90 /* Done by YAMON 2.02 onwards */
91 if (PCI_SLOT(pdev->devfn) == 10) {
92 /*
93 * IDE Decode enable.
94 */
95 pci_read_config_byte(pdev, 0x41, &reg_val);
96 pci_write_config_byte(pdev, 0x41, reg_val|0x80);
97 pci_read_config_byte(pdev, 0x43, &reg_val);
98 pci_write_config_byte(pdev, 0x43, reg_val|0x80);
99 }
100}
101
102DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
103 malta_piix_func1_fixup);
diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c
new file mode 100644
index 00000000000..4975846da75
--- /dev/null
+++ b/arch/mips/pci/fixup-mpc30x.c
@@ -0,0 +1,50 @@
1/*
2 * fixup-mpc30x.c, The Victor MP-C303/304 specific PCI fixups.
3 *
4 * Copyright (C) 2002,2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <linux/init.h>
21#include <linux/pci.h>
22
23#include <asm/vr41xx/mpc30x.h>
24#include <asm/vr41xx/vrc4173.h>
25
26static const int internal_func_irqs[] __initdata = {
27 VRC4173_CASCADE_IRQ,
28 VRC4173_AC97_IRQ,
29 VRC4173_USB_IRQ,
30};
31
32static const int irq_tab_mpc30x[] __initdata = {
33 [12] = VRC4173_PCMCIA1_IRQ,
34 [13] = VRC4173_PCMCIA2_IRQ,
35 [29] = MQ200_IRQ,
36};
37
38int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
39{
40 if (slot == 30)
41 return internal_func_irqs[PCI_FUNC(dev->devfn)];
42
43 return irq_tab_mpc30x[slot];
44}
45
46/* Do platform specific device initialization at pci_enable_device() time */
47int pcibios_plat_dev_init(struct pci_dev *dev)
48{
49 return 0;
50}
diff --git a/arch/mips/pci/fixup-ocelot-c.c b/arch/mips/pci/fixup-ocelot-c.c
new file mode 100644
index 00000000000..d45494807a3
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot-c.c
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Based on work for the Linux port to the Ocelot board, which is
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
8 *
9 * arch/mips/momentum/ocelot_g/pci.c
10 * Board-specific PCI routines for mv64340 controller.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17#include <linux/types.h>
18#include <linux/pci.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21
22int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
23{
24 int bus = dev->bus->number;
25
26 if (bus == 0 && slot == 1)
27 return 2; /* PCI-X A */
28 if (bus == 1 && slot == 1)
29 return 12; /* PCI-X B */
30 if (bus == 1 && slot == 2)
31 return 4; /* PCI B */
32
33return 0;
34 panic("Whooops in pcibios_map_irq");
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/fixup-ocelot-g.c b/arch/mips/pci/fixup-ocelot-g.c
new file mode 100644
index 00000000000..d7a652e326c
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot-g.c
@@ -0,0 +1,37 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
8 */
9#include <linux/types.h>
10#include <linux/pci.h>
11#include <linux/kernel.h>
12#include <linux/init.h>
13
14int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
15{
16 int bus = dev->bus->number;
17
18 if (bus == 0 && slot == 1) /* Intel 82543 Gigabit MAC */
19 return 2; /* irq_nr is 2 for INT0 */
20
21 if (bus == 0 && slot == 2) /* Intel 82543 Gigabit MAC */
22 return 3; /* irq_nr is 3 for INT1 */
23
24 if (bus == 1 && slot == 3) /* Intel 21555 bridge */
25 return 5; /* irq_nr is 8 for INT6 */
26
27 if (bus == 1 && slot == 4) /* PMC Slot */
28 return 9; /* irq_nr is 9 for INT7 */
29
30 return -1;
31}
32
33/* Do platform specific device initialization at pci_enable_device() time */
34int pcibios_plat_dev_init(struct pci_dev *dev)
35{
36 return 0;
37}
diff --git a/arch/mips/pci/fixup-ocelot.c b/arch/mips/pci/fixup-ocelot.c
new file mode 100644
index 00000000000..99629bd047c
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot.c
@@ -0,0 +1,75 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 *
5 * arch/mips/gt64120/momenco_ocelot/pci.c
6 * Board-specific PCI routines for gt64120 controller.
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#include <linux/types.h>
14#include <linux/pci.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <asm/pci.h>
18
19
20void __devinit pcibios_fixup_bus(struct pci_bus *bus)
21{
22 struct pci_bus *current_bus = bus;
23 struct pci_dev *devices;
24 struct list_head *devices_link;
25 u16 cmd;
26
27 list_for_each(devices_link, &(current_bus->devices)) {
28
29 devices = pci_dev_b(devices_link);
30 if (devices == NULL)
31 continue;
32
33 if (PCI_SLOT(devices->devfn) == 1) {
34 /*
35 * Slot 1 is primary ether port, i82559
36 * we double-check against that assumption
37 */
38 if ((devices->vendor != 0x8086) ||
39 (devices->device != 0x1209)) {
40 panic("pcibios_fixup_bus: found "
41 "unexpected PCI device in slot 1.");
42 }
43 devices->irq = 2; /* irq_nr is 2 for INT0 */
44 } else if (PCI_SLOT(devices->devfn) == 2) {
45 /*
46 * Slot 2 is secondary ether port, i21143
47 * we double-check against that assumption
48 */
49 if ((devices->vendor != 0x1011) ||
50 (devices->device != 0x19)) {
51 panic("galileo_pcibios_fixup_bus: "
52 "found unexpected PCI device in slot 2.");
53 }
54 devices->irq = 3; /* irq_nr is 3 for INT1 */
55 } else if (PCI_SLOT(devices->devfn) == 4) {
56 /* PMC Slot 1 */
57 devices->irq = 8; /* irq_nr is 8 for INT6 */
58 } else if (PCI_SLOT(devices->devfn) == 5) {
59 /* PMC Slot 1 */
60 devices->irq = 9; /* irq_nr is 9 for INT7 */
61 } else {
62 /* We don't have assign interrupts for other devices. */
63 devices->irq = 0xff;
64 }
65
66 /* Assign an interrupt number for the device */
67 bus->ops->write_byte(devices, PCI_INTERRUPT_LINE,
68 devices->irq);
69
70 /* enable master */
71 bus->ops->read_word(devices, PCI_COMMAND, &cmd);
72 cmd |= PCI_COMMAND_MASTER;
73 bus->ops->write_word(devices, PCI_COMMAND, cmd);
74 }
75}
diff --git a/arch/mips/pci/fixup-ocelot3.c b/arch/mips/pci/fixup-ocelot3.c
new file mode 100644
index 00000000000..ececc03ec62
--- /dev/null
+++ b/arch/mips/pci/fixup-ocelot3.c
@@ -0,0 +1,41 @@
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 Montavista Software Inc.
7 * Author: Manish Lachwani (mlachwani@mvista.com)
8 *
9 * Looking at the schematics for the Ocelot-3 board, there are
10 * two PCI busses and each bus has two PCI slots.
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/pci.h>
15#include <asm/mipsregs.h>
16
17/*
18 * Do platform specific device initialization at
19 * pci_enable_device() time
20 */
21int pcibios_plat_dev_init(struct pci_dev *dev)
22{
23 return 0;
24}
25
26int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
27{
28 int bus = dev->bus->number;
29
30 if (bus == 0 && slot == 1)
31 return 2; /* PCI-X A */
32 if (bus == 0 && slot == 2)
33 return 3; /* PCI-X B */
34 if (bus == 1 && slot == 1)
35 return 4; /* PCI A */
36 if (bus == 1 && slot == 2)
37 return 5; /* PCI B */
38
39return 0;
40 panic("Whooops in pcibios_map_irq");
41}
diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c
new file mode 100644
index 00000000000..de4e443da20
--- /dev/null
+++ b/arch/mips/pci/fixup-rbtx4927.c
@@ -0,0 +1,140 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * Board specific pci fixups for the Toshiba rbtx4927
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
9 *
10 * Copyright (C) 2000-2001 Toshiba Corporation
11 *
12 * Copyright (C) 2004 MontaVista Software Inc.
13 * Author: Manish Lachwani (mlachwani@mvista.com)
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35#include <linux/types.h>
36#include <linux/pci.h>
37#include <linux/kernel.h>
38#include <linux/init.h>
39
40#include <asm/tx4927/tx4927.h>
41#include <asm/tx4927/tx4927_pci.h>
42
43#undef DEBUG
44#ifdef DEBUG
45#define DBG(x...) printk(x)
46#else
47#define DBG(x...)
48#endif
49
50/* look up table for backplane pci irq for slots 17-20 by pin # */
51static unsigned char backplane_pci_irq[4][4] = {
52 /* PJ6 SLOT: 17, PIN: 1 */ {TX4927_IRQ_IOC_PCIA,
53 /* PJ6 SLOT: 17, PIN: 2 */
54 TX4927_IRQ_IOC_PCIB,
55 /* PJ6 SLOT: 17, PIN: 3 */
56 TX4927_IRQ_IOC_PCIC,
57 /* PJ6 SLOT: 17, PIN: 4 */
58 TX4927_IRQ_IOC_PCID},
59 /* SB SLOT: 18, PIN: 1 */ {TX4927_IRQ_IOC_PCIB,
60 /* SB SLOT: 18, PIN: 2 */
61 TX4927_IRQ_IOC_PCIC,
62 /* SB SLOT: 18, PIN: 3 */
63 TX4927_IRQ_IOC_PCID,
64 /* SB SLOT: 18, PIN: 4 */
65 TX4927_IRQ_IOC_PCIA},
66 /* PJ5 SLOT: 19, PIN: 1 */ {TX4927_IRQ_IOC_PCIC,
67 /* PJ5 SLOT: 19, PIN: 2 */
68 TX4927_IRQ_IOC_PCID,
69 /* PJ5 SLOT: 19, PIN: 3 */
70 TX4927_IRQ_IOC_PCIA,
71 /* PJ5 SLOT: 19, PIN: 4 */
72 TX4927_IRQ_IOC_PCIB},
73 /* PJ4 SLOT: 20, PIN: 1 */ {TX4927_IRQ_IOC_PCID,
74 /* PJ4 SLOT: 20, PIN: 2 */
75 TX4927_IRQ_IOC_PCIA,
76 /* PJ4 SLOT: 20, PIN: 3 */
77 TX4927_IRQ_IOC_PCIB,
78 /* PJ4 SLOT: 20, PIN: 4 */
79 TX4927_IRQ_IOC_PCIC}
80};
81
82int pci_get_irq(struct pci_dev *dev, int pin)
83{
84 unsigned char irq = pin;
85
86 DBG("pci_get_irq: pin is %d\n", pin);
87 /* IRQ rotation */
88 irq--; /* 0-3 */
89 if (dev->bus->parent == NULL &&
90 PCI_SLOT(dev->devfn) == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) {
91 printk("Onboard PCI_SLOT(dev->devfn) is %d\n",
92 PCI_SLOT(dev->devfn));
93 /* IDSEL=A23 is tx4927 onboard pci slot */
94 irq = (irq + PCI_SLOT(dev->devfn)) % 4;
95 irq++; /* 1-4 */
96 DBG("irq is now %d\n", irq);
97
98 switch (irq) {
99 case 1:
100 irq = TX4927_IRQ_IOC_PCIA;
101 break;
102 case 2:
103 irq = TX4927_IRQ_IOC_PCIB;
104 break;
105 case 3:
106 irq = TX4927_IRQ_IOC_PCIC;
107 break;
108 case 4:
109 irq = TX4927_IRQ_IOC_PCID;
110 break;
111 }
112 } else {
113 /* PCI Backplane */
114 DBG("PCI Backplane PCI_SLOT(dev->devfn) is %d\n",
115 PCI_SLOT(dev->devfn));
116 irq = backplane_pci_irq[PCI_SLOT(dev->devfn) - 17][irq];
117 }
118 DBG("assigned irq %d\n", irq);
119 return irq;
120}
121
122int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
123{
124 unsigned char irq;
125
126 printk("PCI Setup for pin %d \n", pin);
127
128 if (dev->device == 0x9130) /* IDE */
129 irq = 14;
130 else
131 irq = pci_get_irq(dev, pin);
132
133 return irq;
134}
135
136/* Do platform specific device initialization at pci_enable_device() time */
137int pcibios_plat_dev_init(struct pci_dev *dev)
138{
139 return 0;
140}
diff --git a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c
new file mode 100644
index 00000000000..13791b78e59
--- /dev/null
+++ b/arch/mips/pci/fixup-sb1250.c
@@ -0,0 +1,24 @@
1/*
2 * arch/mips/pci/fixup-sb1250.c
3 *
4 * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved.
5 * Author: Maciej W. Rozycki <macro@mips.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/pci.h>
15
16/*
17 * The BCM1250, etc. PCI/HT bridge reports as a host bridge.
18 */
19static void __init quirk_sb1250_ht(struct pci_dev *dev)
20{
21 dev->class = PCI_CLASS_BRIDGE_PCI << 8;
22}
23DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
24 quirk_sb1250_ht);
diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c
new file mode 100644
index 00000000000..c8ef01a017c
--- /dev/null
+++ b/arch/mips/pci/fixup-sni.c
@@ -0,0 +1,89 @@
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 * SNI specific PCI support for RM200/RM300.
7 *
8 * Copyright (C) 1997 - 2000, 2003, 04 Ralf Baechle (ralf@linux-mips.org)
9 */
10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/pci.h>
13
14#include <asm/mipsregs.h>
15#include <asm/sni.h>
16
17/*
18 * Shortcuts ...
19 */
20#define SCSI PCIMT_IRQ_SCSI
21#define ETH PCIMT_IRQ_ETHERNET
22#define INTA PCIMT_IRQ_INTA
23#define INTB PCIMT_IRQ_INTB
24#define INTC PCIMT_IRQ_INTC
25#define INTD PCIMT_IRQ_INTD
26
27/*
28 * Device 0: PCI EISA Bridge (directly routed)
29 * Device 1: NCR53c810 SCSI (directly routed)
30 * Device 2: PCnet32 Ethernet (directly routed)
31 * Device 3: VGA (routed to INTB)
32 * Device 4: Unused
33 * Device 5: Slot 2
34 * Device 6: Slot 3
35 * Device 7: Slot 4
36 *
37 * Documentation says the VGA is device 5 and device 3 is unused but that
38 * seem to be a documentation error. At least on my RM200C the Cirrus
39 * Logic CL-GD5434 VGA is device 3.
40 */
41static char irq_tab_rm200[8][5] __initdata = {
42 /* INTA INTB INTC INTD */
43 { 0, 0, 0, 0, 0 }, /* EISA bridge */
44 { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */
45 { ETH, ETH, ETH, ETH, ETH }, /* Ethernet */
46 { INTB, INTB, INTB, INTB, INTB }, /* VGA */
47 { 0, 0, 0, 0, 0 }, /* Unused */
48 { 0, INTB, INTC, INTD, INTA }, /* Slot 2 */
49 { 0, INTC, INTD, INTA, INTB }, /* Slot 3 */
50 { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */
51};
52
53/*
54 * In Revision D of the RM300 Device 2 has become a normal purpose Slot 1
55 *
56 * The VGA card is optional for RM300 systems.
57 */
58static char irq_tab_rm300d[8][5] __initdata = {
59 /* INTA INTB INTC INTD */
60 { 0, 0, 0, 0, 0 }, /* EISA bridge */
61 { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */
62 { 0, INTC, INTD, INTA, INTB }, /* Slot 1 */
63 { INTB, INTB, INTB, INTB, INTB }, /* VGA */
64 { 0, 0, 0, 0, 0 }, /* Unused */
65 { 0, INTB, INTC, INTD, INTA }, /* Slot 2 */
66 { 0, INTC, INTD, INTA, INTB }, /* Slot 3 */
67 { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */
68};
69
70static inline int is_rm300_revd(void)
71{
72 unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
73
74 return (csmsr & 0xa0) == 0x20;
75}
76
77int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
78{
79 if (is_rm300_revd())
80 return irq_tab_rm300d[slot][pin];
81
82 return irq_tab_rm200[slot][pin];
83}
84
85/* Do platform specific device initialization at pci_enable_device() time */
86int pcibios_plat_dev_init(struct pci_dev *dev)
87{
88 return 0;
89}
diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c
new file mode 100644
index 00000000000..850a900f0eb
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0219.c
@@ -0,0 +1,66 @@
1/*
2 * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
3 *
4 * Copyright (C) 2003 Megasolution Inc. <matsu@megasolution.jp>
5 * Copyright (C) 2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include <linux/init.h>
22#include <linux/pci.h>
23
24#include <asm/vr41xx/tb0219.h>
25
26int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
27{
28 int irq = -1;
29
30 switch (slot) {
31 case 12:
32 vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN,
33 TRIGGER_LEVEL,
34 SIGNAL_THROUGH);
35 vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN,
36 LEVEL_LOW);
37 irq = TB0219_PCI_SLOT1_IRQ;
38 break;
39 case 13:
40 vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN,
41 TRIGGER_LEVEL,
42 SIGNAL_THROUGH);
43 vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN,
44 LEVEL_LOW);
45 irq = TB0219_PCI_SLOT2_IRQ;
46 break;
47 case 14:
48 vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN,
49 TRIGGER_LEVEL,
50 SIGNAL_THROUGH);
51 vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN,
52 LEVEL_LOW);
53 irq = TB0219_PCI_SLOT3_IRQ;
54 break;
55 default:
56 break;
57 }
58
59 return irq;
60}
61
62/* Do platform specific device initialization at pci_enable_device() time */
63int pcibios_plat_dev_init(struct pci_dev *dev)
64{
65 return 0;
66}
diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c
new file mode 100644
index 00000000000..61513d5d97d
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0226.c
@@ -0,0 +1,85 @@
1/*
2 * fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups.
3 *
4 * Copyright (C) 2002-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <linux/init.h>
21#include <linux/pci.h>
22
23#include <asm/vr41xx/tb0226.h>
24
25int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
26{
27 int irq = -1;
28
29 switch (slot) {
30 case 12:
31 vr41xx_set_irq_trigger(GD82559_1_PIN,
32 TRIGGER_LEVEL,
33 SIGNAL_THROUGH);
34 vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW);
35 irq = GD82559_1_IRQ;
36 break;
37 case 13:
38 vr41xx_set_irq_trigger(GD82559_2_PIN,
39 TRIGGER_LEVEL,
40 SIGNAL_THROUGH);
41 vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW);
42 irq = GD82559_2_IRQ;
43 break;
44 case 14:
45 switch (pin) {
46 case 1:
47 vr41xx_set_irq_trigger(UPD720100_INTA_PIN,
48 TRIGGER_LEVEL,
49 SIGNAL_THROUGH);
50 vr41xx_set_irq_level(UPD720100_INTA_PIN,
51 LEVEL_LOW);
52 irq = UPD720100_INTA_IRQ;
53 break;
54 case 2:
55 vr41xx_set_irq_trigger(UPD720100_INTB_PIN,
56 TRIGGER_LEVEL,
57 SIGNAL_THROUGH);
58 vr41xx_set_irq_level(UPD720100_INTB_PIN,
59 LEVEL_LOW);
60 irq = UPD720100_INTB_IRQ;
61 break;
62 case 3:
63 vr41xx_set_irq_trigger(UPD720100_INTC_PIN,
64 TRIGGER_LEVEL,
65 SIGNAL_THROUGH);
66 vr41xx_set_irq_level(UPD720100_INTC_PIN,
67 LEVEL_LOW);
68 irq = UPD720100_INTC_IRQ;
69 break;
70 default:
71 break;
72 }
73 break;
74 default:
75 break;
76 }
77
78 return irq;
79}
80
81/* Do platform specific device initialization at pci_enable_device() time */
82int pcibios_plat_dev_init(struct pci_dev *dev)
83{
84 return 0;
85}
diff --git a/arch/mips/pci/fixup-vr4133.c b/arch/mips/pci/fixup-vr4133.c
new file mode 100644
index 00000000000..03a0ff2fc99
--- /dev/null
+++ b/arch/mips/pci/fixup-vr4133.c
@@ -0,0 +1,204 @@
1/*
2 * arch/mips/vr41xx/nec-cmbvr4133/pci_fixup.c
3 *
4 * The NEC CMB-VR4133 Board specific PCI fixups.
5 *
6 * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
7 * Alex Sapkov <asapkov@ru.mvista.com>
8 *
9 * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 *
14 * Modified for support in 2.6
15 * Author: Manish Lachwani (mlachwani@mvista.com)
16 *
17 */
18#include <linux/config.h>
19#include <linux/init.h>
20#include <linux/pci.h>
21
22#include <asm/io.h>
23#include <asm/vr41xx/cmbvr4133.h>
24
25extern int vr4133_rockhopper;
26extern void ali_m1535plus_init(struct pci_dev *dev);
27extern void ali_m5229_init(struct pci_dev *dev);
28
29/* Do platform specific device initialization at pci_enable_device() time */
30int pcibios_plat_dev_init(struct pci_dev *dev)
31{
32 /*
33 * We have to reset AMD PCnet adapter on Rockhopper since
34 * PMON leaves it enabled and generating interrupts. This leads
35 * to a lock if some PCI device driver later enables the IRQ line
36 * shared with PCnet and there is no AMD PCnet driver to catch its
37 * interrupts.
38 */
39#ifdef CONFIG_ROCKHOPPER
40 if (dev->vendor == PCI_VENDOR_ID_AMD &&
41 dev->device == PCI_DEVICE_ID_AMD_LANCE) {
42 inl(pci_resource_start(dev, 0) + 0x18);
43 }
44#endif
45
46 /*
47 * we have to open the bridges' windows down to 0 because otherwise
48 * we cannot access ISA south bridge I/O registers that get mapped from
49 * 0. for example, 8259 PIC would be unaccessible without that
50 */
51 if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) {
52 pci_write_config_byte(dev, PCI_IO_BASE, 0);
53 if(dev->bus->number == 0) {
54 pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
55 } else {
56 pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1);
57 }
58 }
59
60 return 0;
61}
62
63/*
64 * M1535 IRQ mapping
65 * Feel free to change this, although it shouldn't be needed
66 */
67#define M1535_IRQ_INTA 7
68#define M1535_IRQ_INTB 9
69#define M1535_IRQ_INTC 10
70#define M1535_IRQ_INTD 11
71
72#define M1535_IRQ_USB 9
73#define M1535_IRQ_IDE 14
74#define M1535_IRQ_IDE2 15
75#define M1535_IRQ_PS2 12
76#define M1535_IRQ_RTC 8
77#define M1535_IRQ_FDC 6
78#define M1535_IRQ_AUDIO 5
79#define M1535_IRQ_COM1 4
80#define M1535_IRQ_COM2 4
81#define M1535_IRQ_IRDA 3
82#define M1535_IRQ_KBD 1
83#define M1535_IRQ_TMR 0
84
85/* Rockhopper "slots" assignment; this is hard-coded ... */
86#define ROCKHOPPER_M5451_SLOT 1
87#define ROCKHOPPER_M1535_SLOT 2
88#define ROCKHOPPER_M5229_SLOT 11
89#define ROCKHOPPER_M5237_SLOT 15
90#define ROCKHOPPER_PMU_SLOT 12
91/* ... and hard-wired. */
92#define ROCKHOPPER_PCI1_SLOT 3
93#define ROCKHOPPER_PCI2_SLOT 4
94#define ROCKHOPPER_PCI3_SLOT 5
95#define ROCKHOPPER_PCI4_SLOT 6
96#define ROCKHOPPER_PCNET_SLOT 1
97
98#define M1535_IRQ_MASK(n) (1 << (n))
99
100#define M1535_IRQ_EDGE (M1535_IRQ_MASK(M1535_IRQ_TMR) | \
101 M1535_IRQ_MASK(M1535_IRQ_KBD) | \
102 M1535_IRQ_MASK(M1535_IRQ_COM1) | \
103 M1535_IRQ_MASK(M1535_IRQ_COM2) | \
104 M1535_IRQ_MASK(M1535_IRQ_IRDA) | \
105 M1535_IRQ_MASK(M1535_IRQ_RTC) | \
106 M1535_IRQ_MASK(M1535_IRQ_FDC) | \
107 M1535_IRQ_MASK(M1535_IRQ_PS2))
108
109#define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE) | \
110 M1535_IRQ_MASK(M1535_IRQ_USB) | \
111 M1535_IRQ_MASK(M1535_IRQ_INTA) | \
112 M1535_IRQ_MASK(M1535_IRQ_INTB) | \
113 M1535_IRQ_MASK(M1535_IRQ_INTC) | \
114 M1535_IRQ_MASK(M1535_IRQ_INTD))
115
116struct irq_map_entry {
117 u16 bus;
118 u8 slot;
119 u8 irq;
120};
121static struct irq_map_entry int_map[] = {
122 {1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO}, /* Audio controller */
123 {1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD}, /* PCI slot #1 */
124 {1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC}, /* PCI slot #2 */
125 {1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB}, /* USB host controller */
126 {1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ}, /* IDE controller */
127 {2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD}, /* AMD Am79c973 on-board
128 ethernet */
129 {2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB}, /* PCI slot #3 */
130 {2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC} /* PCI slot #4 */
131};
132
133static int pci_intlines[] =
134 { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD };
135
136/* Determine the Rockhopper IRQ line number for the PCI device */
137int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot)
138{
139 struct pci_bus *bus;
140 int i;
141
142 bus = dev->bus;
143 if (bus == NULL)
144 return -1;
145
146 for (i = 0; i < sizeof (int_map) / sizeof (int_map[0]); i++) {
147 if (int_map[i].bus == bus->number && int_map[i].slot == slot) {
148 int line;
149 for (line = 0; line < 4; line++)
150 if (pci_intlines[line] == int_map[i].irq)
151 break;
152 if (line < 4)
153 return pci_intlines[(line + (pin - 1)) % 4];
154 else
155 return int_map[i].irq;
156 }
157 }
158 return -1;
159}
160
161#ifdef CONFIG_ROCKHOPPER
162void i8259_init(void)
163{
164 outb(0x11, 0x20); /* Master ICW1 */
165 outb(I8259_IRQ_BASE, 0x21); /* Master ICW2 */
166 outb(0x04, 0x21); /* Master ICW3 */
167 outb(0x01, 0x21); /* Master ICW4 */
168 outb(0xff, 0x21); /* Master IMW */
169
170 outb(0x11, 0xa0); /* Slave ICW1 */
171 outb(I8259_IRQ_BASE + 8, 0xa1); /* Slave ICW2 */
172 outb(0x02, 0xa1); /* Slave ICW3 */
173 outb(0x01, 0xa1); /* Slave ICW4 */
174 outb(0xff, 0xa1); /* Slave IMW */
175
176 outb(0x00, 0x4d0);
177 outb(0x02, 0x4d1); /* USB IRQ9 is level */
178}
179#endif
180
181int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
182{
183 extern int pci_probe_only;
184 pci_probe_only = 1;
185
186#ifdef CONFIG_ROCKHOPPER
187 if( dev->bus->number == 1 && vr4133_rockhopper ) {
188 if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT)
189 dev->irq = CMBVR41XX_INTA_IRQ;
190 else
191 dev->irq = rockhopper_get_irq(dev, pin, slot);
192 } else
193 dev->irq = CMBVR41XX_INTA_IRQ;
194#else
195 dev->irq = CMBVR41XX_INTA_IRQ;
196#endif
197
198 return dev->irq;
199}
200
201DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init);
202DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init);
203
204
diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c
new file mode 100644
index 00000000000..81d77a587a5
--- /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(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..c1c91ca0f9c
--- /dev/null
+++ b/arch/mips/pci/ops-au1000.c
@@ -0,0 +1,325 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Alchemy/AMD Au1x00 pci support.
4 *
5 * Copyright 2001,2002,2003 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * Support for all devices (greater than 16) added by David Gathright.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31#include <linux/config.h>
32#include <linux/types.h>
33#include <linux/pci.h>
34#include <linux/kernel.h>
35#include <linux/init.h>
36#include <linux/vmalloc.h>
37
38#include <asm/mach-au1x00/au1000.h>
39
40#undef DEBUG
41#ifdef DEBUG
42#define DBG(x...) printk(x)
43#else
44#define DBG(x...)
45#endif
46
47#define PCI_ACCESS_READ 0
48#define PCI_ACCESS_WRITE 1
49
50
51int (*board_pci_idsel)(unsigned int devsel, int assert);
52
53/* CP0 hazard avoidance. */
54#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
55 "nop; nop; nop; nop;\t" \
56 ".set reorder\n\t")
57
58void mod_wired_entry(int entry, unsigned long entrylo0,
59 unsigned long entrylo1, unsigned long entryhi,
60 unsigned long pagemask)
61{
62 unsigned long old_pagemask;
63 unsigned long old_ctx;
64
65 /* Save old context and create impossible VPN2 value */
66 old_ctx = read_c0_entryhi() & 0xff;
67 old_pagemask = read_c0_pagemask();
68 write_c0_index(entry);
69 BARRIER;
70 write_c0_pagemask(pagemask);
71 write_c0_entryhi(entryhi);
72 write_c0_entrylo0(entrylo0);
73 write_c0_entrylo1(entrylo1);
74 BARRIER;
75 tlb_write_indexed();
76 BARRIER;
77 write_c0_entryhi(old_ctx);
78 BARRIER;
79 write_c0_pagemask(old_pagemask);
80}
81
82struct vm_struct *pci_cfg_vm;
83static int pci_cfg_wired_entry;
84static int first_cfg = 1;
85unsigned long last_entryLo0, last_entryLo1;
86
87static int config_access(unsigned char access_type, struct pci_bus *bus,
88 unsigned int dev_fn, unsigned char where,
89 u32 * data)
90{
91#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
92 unsigned int device = PCI_SLOT(dev_fn);
93 unsigned int function = PCI_FUNC(dev_fn);
94 unsigned long offset, status;
95 unsigned long cfg_base;
96 unsigned long flags;
97 int error = PCIBIOS_SUCCESSFUL;
98 unsigned long entryLo0, entryLo1;
99
100 if (device > 19) {
101 *data = 0xffffffff;
102 return -1;
103 }
104
105 local_irq_save(flags);
106 au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
107 Au1500_PCI_STATCMD);
108 au_sync_udelay(1);
109
110 /*
111 * We can't ioremap the entire pci config space because it's
112 * too large. Nor can we call ioremap dynamically because some
113 * device drivers use the pci config routines from within
114 * interrupt handlers and that becomes a problem in get_vm_area().
115 * We use one wired tlb to handle all config accesses for all
116 * busses. To improve performance, if the current device
117 * is the same as the last device accessed, we don't touch the
118 * tlb.
119 */
120 if (first_cfg) {
121 /* reserve a wired entry for pci config accesses */
122 first_cfg = 0;
123 pci_cfg_vm = get_vm_area(0x2000, 0);
124 if (!pci_cfg_vm)
125 panic (KERN_ERR "PCI unable to get vm area\n");
126 pci_cfg_wired_entry = read_c0_wired();
127 add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K);
128 last_entryLo0 = last_entryLo1 = 0xffffffff;
129 }
130
131 /* Since the Au1xxx doesn't do the idsel timing exactly to spec,
132 * many board vendors implement their own off-chip idsel, so call
133 * it now. If it doesn't succeed, may as well bail out at this point.
134 */
135 if (board_pci_idsel) {
136 if (board_pci_idsel(device, 1) == 0) {
137 *data = 0xffffffff;
138 local_irq_restore(flags);
139 return -1;
140 }
141 }
142
143 /* setup the config window */
144 if (bus->number == 0) {
145 cfg_base = ((1<<device)<<11);
146 } else {
147 cfg_base = 0x80000000 | (bus->number<<16) | (device<<11);
148 }
149
150 /* setup the lower bits of the 36 bit address */
151 offset = (function << 8) | (where & ~0x3);
152 /* pick up any address that falls below the page mask */
153 offset |= cfg_base & ~PAGE_MASK;
154
155 /* page boundary */
156 cfg_base = cfg_base & PAGE_MASK;
157
158 entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
159 entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
160
161 if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
162 mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
163 (unsigned long)pci_cfg_vm->addr, PM_4K);
164 last_entryLo0 = entryLo0;
165 last_entryLo1 = entryLo1;
166 }
167
168 if (access_type == PCI_ACCESS_WRITE) {
169 au_writel(*data, (int)(pci_cfg_vm->addr + offset));
170 } else {
171 *data = au_readl((int)(pci_cfg_vm->addr + offset));
172 }
173 au_sync_udelay(2);
174
175 DBG("cfg_access %d bus->number %d dev %d at %x *data %x conf %x\n",
176 access_type, bus->number, device, where, *data, offset);
177
178 /* check master abort */
179 status = au_readl(Au1500_PCI_STATCMD);
180
181 if (status & (1<<29)) {
182 *data = 0xffffffff;
183 error = -1;
184 DBG("Au1x Master Abort\n");
185 } else if ((status >> 28) & 0xf) {
186 DBG("PCI ERR detected: status %x\n", status);
187 *data = 0xffffffff;
188 error = -1;
189 }
190
191 /* Take away the idsel.
192 */
193 if (board_pci_idsel) {
194 (void)board_pci_idsel(device, 0);
195 }
196
197 local_irq_restore(flags);
198 return error;
199#endif
200}
201
202static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
203 int where, u8 * val)
204{
205 u32 data;
206 int ret;
207
208 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
209 if (where & 1)
210 data >>= 8;
211 if (where & 2)
212 data >>= 16;
213 *val = data & 0xff;
214 return ret;
215}
216
217
218static int read_config_word(struct pci_bus *bus, unsigned int devfn,
219 int where, u16 * val)
220{
221 u32 data;
222 int ret;
223
224 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
225 if (where & 2)
226 data >>= 16;
227 *val = data & 0xffff;
228 return ret;
229}
230
231static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
232 int where, u32 * val)
233{
234 int ret;
235
236 ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
237 return ret;
238}
239
240static int
241write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
242 u8 val)
243{
244 u32 data = 0;
245
246 if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
247 return -1;
248
249 data = (data & ~(0xff << ((where & 3) << 3))) |
250 (val << ((where & 3) << 3));
251
252 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
253 return -1;
254
255 return PCIBIOS_SUCCESSFUL;
256}
257
258static int
259write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
260 u16 val)
261{
262 u32 data = 0;
263
264 if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
265 return -1;
266
267 data = (data & ~(0xffff << ((where & 3) << 3))) |
268 (val << ((where & 3) << 3));
269
270 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
271 return -1;
272
273
274 return PCIBIOS_SUCCESSFUL;
275}
276
277static int
278write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
279 u32 val)
280{
281 if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
282 return -1;
283
284 return PCIBIOS_SUCCESSFUL;
285}
286
287static int config_read(struct pci_bus *bus, unsigned int devfn,
288 int where, int size, u32 * val)
289{
290 switch (size) {
291 case 1: {
292 u8 _val;
293 int rc = read_config_byte(bus, devfn, where, &_val);
294 *val = _val;
295 return rc;
296 }
297 case 2: {
298 u16 _val;
299 int rc = read_config_word(bus, devfn, where, &_val);
300 *val = _val;
301 return rc;
302 }
303 default:
304 return read_config_dword(bus, devfn, where, val);
305 }
306}
307
308static int config_write(struct pci_bus *bus, unsigned int devfn,
309 int where, int size, u32 val)
310{
311 switch (size) {
312 case 1:
313 return write_config_byte(bus, devfn, where, (u8) val);
314 case 2:
315 return write_config_word(bus, devfn, where, (u16) val);
316 default:
317 return write_config_dword(bus, devfn, where, val);
318 }
319}
320
321
322struct pci_ops au1x_pci_ops = {
323 config_read,
324 config_write
325};
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
new file mode 100644
index 00000000000..4b4e086a7eb
--- /dev/null
+++ b/arch/mips/pci/ops-bonito64.c
@@ -0,0 +1,196 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * MIPS boards specific PCI support.
19 */
20#include <linux/config.h>
21#include <linux/types.h>
22#include <linux/pci.h>
23#include <linux/kernel.h>
24#include <linux/init.h>
25
26#include <asm/mips-boards/bonito64.h>
27
28#define PCI_ACCESS_READ 0
29#define PCI_ACCESS_WRITE 1
30
31/*
32 * PCI configuration cycle AD bus definition
33 */
34/* Type 0 */
35#define PCI_CFG_TYPE0_REG_SHF 0
36#define PCI_CFG_TYPE0_FUNC_SHF 8
37
38/* Type 1 */
39#define PCI_CFG_TYPE1_REG_SHF 0
40#define PCI_CFG_TYPE1_FUNC_SHF 8
41#define PCI_CFG_TYPE1_DEV_SHF 11
42#define PCI_CFG_TYPE1_BUS_SHF 16
43
44static int bonito64_pcibios_config_access(unsigned char access_type,
45 struct pci_bus *bus,
46 unsigned int devfn, int where,
47 u32 * data)
48{
49 unsigned char busnum = bus->number;
50 u32 dummy;
51 u64 pci_addr;
52
53 /* Algorithmics Bonito64 system controller. */
54
55 if ((busnum == 0) && (PCI_SLOT(devfn) > 21)) {
56 /* We number bus 0 devices from 0..21 */
57 return -1;
58 }
59
60#ifdef CONFIG_MIPS_BOARDS_GEN
61 if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
62 /* MIPS Core boards have Bonito connected as device 17 */
63 return -1;
64 }
65#endif
66
67 /* Clear cause register bits */
68 BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
69 BONITO_PCICMD_MTABORT_CLR);
70
71 /*
72 * Setup pattern to be used as PCI "address" for
73 * Type 0 cycle
74 */
75 if (busnum == 0) {
76 /* IDSEL */
77 pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10);
78 } else {
79 /* Bus number */
80 pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF;
81
82 /* Device number */
83 pci_addr |=
84 PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF;
85 }
86
87 /* Function (same for Type 0/1) */
88 pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF;
89
90 /* Register number (same for Type 0/1) */
91 pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
92
93 if (busnum == 0) {
94 /* Type 0 */
95 BONITO_PCIMAP_CFG = pci_addr >> 16;
96 } else {
97 /* Type 1 */
98 BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
99 }
100
101 pci_addr &= 0xffff;
102
103 /* Flush Bonito register block */
104 dummy = BONITO_PCIMAP_CFG;
105 iob(); /* sync */
106
107 /* Perform access */
108 if (access_type == PCI_ACCESS_WRITE) {
109 *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr) = *(u32 *) data;
110
111 /* Wait till done */
112 while (BONITO_PCIMSTAT & 0xF);
113 } else {
114 *(u32 *) data = *(volatile u32 *) (_pcictrl_bonito_pcicfg + (u32)pci_addr);
115 }
116
117 /* Detect Master/Target abort */
118 if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR |
119 BONITO_PCICMD_MTABORT_CLR)) {
120 /* Error occurred */
121
122 /* Clear bits */
123 BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
124 BONITO_PCICMD_MTABORT_CLR);
125
126 return -1;
127 }
128
129 return 0;
130}
131
132
133/*
134 * We can't address 8 and 16 bit words directly. Instead we have to
135 * read/write a 32bit word and mask/modify the data we actually want.
136 */
137static int bonito64_pcibios_read(struct pci_bus *bus, unsigned int devfn,
138 int where, int size, u32 * val)
139{
140 u32 data = 0;
141
142 if ((size == 2) && (where & 1))
143 return PCIBIOS_BAD_REGISTER_NUMBER;
144 else if ((size == 4) && (where & 3))
145 return PCIBIOS_BAD_REGISTER_NUMBER;
146
147 if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
148 &data))
149 return -1;
150
151 if (size == 1)
152 *val = (data >> ((where & 3) << 3)) & 0xff;
153 else if (size == 2)
154 *val = (data >> ((where & 3) << 3)) & 0xffff;
155 else
156 *val = data;
157
158 return PCIBIOS_SUCCESSFUL;
159}
160
161static int bonito64_pcibios_write(struct pci_bus *bus, unsigned int devfn,
162 int where, int size, u32 val)
163{
164 u32 data = 0;
165
166 if ((size == 2) && (where & 1))
167 return PCIBIOS_BAD_REGISTER_NUMBER;
168 else if ((size == 4) && (where & 3))
169 return PCIBIOS_BAD_REGISTER_NUMBER;
170
171 if (size == 4)
172 data = val;
173 else {
174 if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
175 where, &data))
176 return -1;
177
178 if (size == 1)
179 data = (data & ~(0xff << ((where & 3) << 3))) |
180 (val << ((where & 3) << 3));
181 else if (size == 2)
182 data = (data & ~(0xffff << ((where & 3) << 3))) |
183 (val << ((where & 3) << 3));
184 }
185
186 if (bonito64_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
187 &data))
188 return -1;
189
190 return PCIBIOS_SUCCESSFUL;
191}
192
193struct pci_ops bonito64_pci_ops = {
194 .read = bonito64_pcibios_read,
195 .write = bonito64_pcibios_write
196};
diff --git a/arch/mips/pci/ops-ddb5074.c b/arch/mips/pci/ops-ddb5074.c
new file mode 100644
index 00000000000..89f97bef4fc
--- /dev/null
+++ b/arch/mips/pci/ops-ddb5074.c
@@ -0,0 +1,271 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 *
5 * arch/mips/ddb5xxx/ddb5476/pci_ops.c
6 * Define the pci_ops for DB5477.
7 *
8 * Much of the code is derived from the original DDB5074 port by
9 * Geert Uytterhoeven <geert@sonycom.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17#include <linux/pci.h>
18#include <linux/kernel.h>
19#include <linux/types.h>
20
21#include <asm/addrspace.h>
22#include <asm/debug.h>
23
24#include <asm/ddb5xxx/ddb5xxx.h>
25
26/*
27 * config_swap structure records what set of pdar/pmr are used
28 * to access pci config space. It also provides a place hold the
29 * original values for future restoring.
30 */
31struct pci_config_swap {
32 u32 pdar;
33 u32 pmr;
34 u32 config_base;
35 u32 config_size;
36 u32 pdar_backup;
37 u32 pmr_backup;
38};
39
40/*
41 * On DDB5476, we have one set of swap registers
42 */
43struct pci_config_swap ext_pci_swap = {
44 DDB_PCIW0,
45 DDB_PCIINIT0,
46 DDB_PCI_CONFIG_BASE,
47 DDB_PCI_CONFIG_SIZE
48};
49
50static int pci_config_workaround = 1;
51
52/*
53 * access config space
54 */
55static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus, /* 0 means top level bus */
56 u32 slot_num)
57{
58 u32 pci_addr = 0;
59 u32 pciinit_offset = 0;
60 u32 virt_addr = swap->config_base;
61 u32 option;
62
63 if (pci_config_workaround) {
64 if (slot_num == 5)
65 slot_num = 14;
66 } else {
67 if (slot_num == 5)
68 return DDB_BASE + DDB_PCI_BASE;
69 }
70
71 /* minimum pdar (window) size is 2MB */
72 db_assert(swap->config_size >= (2 << 20));
73
74 db_assert(slot_num < (1 << 5));
75 db_assert(bus < (1 << 8));
76
77 /* backup registers */
78 swap->pdar_backup = ddb_in32(swap->pdar);
79 swap->pmr_backup = ddb_in32(swap->pmr);
80
81 /* set the pdar (pci window) register */
82 ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32, /* 32 bit wide */
83 0, /* not on local memory bus */
84 0); /* not visible from PCI bus (N/A) */
85
86 /*
87 * calcuate the absolute pci config addr;
88 * according to the spec, we start scanning from adr:11 (0x800)
89 */
90 if (bus == 0) {
91 /* type 0 config */
92 pci_addr = 0x00040000 << slot_num;
93 } else {
94 /* type 1 config */
95 pci_addr = 0x00040000 << slot_num;
96 panic
97 ("ddb_access_config_base: we don't support type 1 config Yet");
98 }
99
100 /*
101 * if pci_addr is less than pci config window size, we set
102 * pciinit_offset to 0 and adjust the virt_address.
103 * Otherwise we will try to adjust pciinit_offset.
104 */
105 if (pci_addr < swap->config_size) {
106 virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
107 pciinit_offset = 0;
108 } else {
109 db_assert((pci_addr & (swap->config_size - 1)) == 0);
110 virt_addr = KSEG1ADDR(swap->config_base);
111 pciinit_offset = pci_addr;
112 }
113
114 /* set the pmr register */
115 option = DDB_PCI_ACCESS_32;
116 if (bus != 0)
117 option |= DDB_PCI_CFGTYPE1;
118 ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
119
120 return virt_addr;
121}
122
123static inline void ddb_close_config_base(struct pci_config_swap *swap)
124{
125 ddb_out32(swap->pdar, swap->pdar_backup);
126 ddb_out32(swap->pmr, swap->pmr_backup);
127}
128
129static int read_config_dword(struct pci_config_swap *swap,
130 struct pci_dev *dev, u32 where, u32 * val)
131{
132 u32 bus, slot_num, func_num;
133 u32 base;
134
135 db_assert((where & 3) == 0);
136 db_assert(where < (1 << 8));
137
138 /* check if the bus is top-level */
139 if (dev->bus->parent != NULL) {
140 bus = dev->bus->number;
141 db_assert(bus != 0);
142 } else {
143 bus = 0;
144 }
145
146 slot_num = PCI_SLOT(dev->devfn);
147 func_num = PCI_FUNC(dev->devfn);
148 base = ddb_access_config_base(swap, bus, slot_num);
149 *val = *(volatile u32 *) (base + (func_num << 8) + where);
150 ddb_close_config_base(swap);
151 return PCIBIOS_SUCCESSFUL;
152}
153
154static int read_config_word(struct pci_config_swap *swap,
155 struct pci_dev *dev, u32 where, u16 * val)
156{
157 int status;
158 u32 result;
159
160 db_assert((where & 1) == 0);
161
162 status = read_config_dword(swap, dev, where & ~3, &result);
163 if (where & 2)
164 result >>= 16;
165 *val = result & 0xffff;
166 return status;
167}
168
169static int read_config_byte(struct pci_config_swap *swap,
170 struct pci_dev *dev, u32 where, u8 * val)
171{
172 int status;
173 u32 result;
174
175 status = read_config_dword(swap, dev, where & ~3, &result);
176 if (where & 1)
177 result >>= 8;
178 if (where & 2)
179 result >>= 16;
180 *val = result & 0xff;
181 return status;
182}
183
184static int write_config_dword(struct pci_config_swap *swap,
185 struct pci_dev *dev, u32 where, u32 val)
186{
187 u32 bus, slot_num, func_num;
188 u32 base;
189
190 db_assert((where & 3) == 0);
191 db_assert(where < (1 << 8));
192
193 /* check if the bus is top-level */
194 if (dev->bus->parent != NULL) {
195 bus = dev->bus->number;
196 db_assert(bus != 0);
197 } else {
198 bus = 0;
199 }
200
201 slot_num = PCI_SLOT(dev->devfn);
202 func_num = PCI_FUNC(dev->devfn);
203 base = ddb_access_config_base(swap, bus, slot_num);
204 *(volatile u32 *) (base + (func_num << 8) + where) = val;
205 ddb_close_config_base(swap);
206 return PCIBIOS_SUCCESSFUL;
207}
208
209static int write_config_word(struct pci_config_swap *swap,
210 struct pci_dev *dev, u32 where, u16 val)
211{
212 int status, shift = 0;
213 u32 result;
214
215 db_assert((where & 1) == 0);
216
217 status = read_config_dword(swap, dev, where & ~3, &result);
218 if (status != PCIBIOS_SUCCESSFUL)
219 return status;
220
221 if (where & 2)
222 shift += 16;
223 result &= ~(0xffff << shift);
224 result |= val << shift;
225 return write_config_dword(swap, dev, where & ~3, result);
226}
227
228static int write_config_byte(struct pci_config_swap *swap,
229 struct pci_dev *dev, u32 where, u8 val)
230{
231 int status, shift = 0;
232 u32 result;
233
234 status = read_config_dword(swap, dev, where & ~3, &result);
235 if (status != PCIBIOS_SUCCESSFUL)
236 return status;
237
238 if (where & 2)
239 shift += 16;
240 if (where & 1)
241 shift += 8;
242 result &= ~(0xff << shift);
243 result |= val << shift;
244 return write_config_dword(swap, dev, where & ~3, result);
245}
246
247#define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
248static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
249{ \
250 return rw##_config_##unitname(pciswap, \
251 dev, \
252 where, \
253 val); \
254}
255
256MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
257 MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
258 MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
259
260 MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
261 MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
262 MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
263
264struct pci_ops ddb5476_ext_pci_ops = {
265 extpci_read_config_byte,
266 extpci_read_config_word,
267 extpci_read_config_dword,
268 extpci_write_config_byte,
269 extpci_write_config_word,
270 extpci_write_config_dword
271};
diff --git a/arch/mips/pci/ops-ddb5476.c b/arch/mips/pci/ops-ddb5476.c
new file mode 100644
index 00000000000..12da58e75ec
--- /dev/null
+++ b/arch/mips/pci/ops-ddb5476.c
@@ -0,0 +1,286 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 *
5 * arch/mips/ddb5xxx/ddb5476/pci_ops.c
6 * Define the pci_ops for DB5477.
7 *
8 * Much of the code is derived from the original DDB5074 port by
9 * Geert Uytterhoeven <geert@sonycom.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17#include <linux/pci.h>
18#include <linux/kernel.h>
19#include <linux/types.h>
20
21#include <asm/addrspace.h>
22#include <asm/debug.h>
23
24#include <asm/ddb5xxx/ddb5xxx.h>
25
26/*
27 * config_swap structure records what set of pdar/pmr are used
28 * to access pci config space. It also provides a place hold the
29 * original values for future restoring.
30 */
31struct pci_config_swap {
32 u32 pdar;
33 u32 pmr;
34 u32 config_base;
35 u32 config_size;
36 u32 pdar_backup;
37 u32 pmr_backup;
38};
39
40/*
41 * On DDB5476, we have one set of swap registers
42 */
43struct pci_config_swap ext_pci_swap = {
44 DDB_PCIW0,
45 DDB_PCIINIT0,
46 DDB_PCI_CONFIG_BASE,
47 DDB_PCI_CONFIG_SIZE
48};
49
50static int pci_config_workaround = 1;
51
52/*
53 * access config space
54 */
55static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus, /* 0 means top level bus */
56 u32 slot_num)
57{
58 u32 pci_addr = 0;
59 u32 pciinit_offset = 0;
60 u32 virt_addr = swap->config_base;
61 u32 option;
62
63 if (pci_config_workaround) {
64 /* [jsun] work around Vrc5476 controller itself, returnning
65 * slot 0 essentially makes vrc5476 invisible
66 */
67 if (slot_num == 12)
68 slot_num = 0;
69
70#if 0
71 /* BUG : skip P2P bridge for now */
72 if (slot_num == 5)
73 slot_num = 0;
74#endif
75
76 } else {
77 /* now we have to be hornest, returning the true
78 * PCI config headers for vrc5476
79 */
80 if (slot_num == 12) {
81 swap->pdar_backup = ddb_in32(swap->pdar);
82 swap->pmr_backup = ddb_in32(swap->pmr);
83 return DDB_BASE + DDB_PCI_BASE;
84 }
85 }
86
87 /* minimum pdar (window) size is 2MB */
88 db_assert(swap->config_size >= (2 << 20));
89
90 db_assert(slot_num < (1 << 5));
91 db_assert(bus < (1 << 8));
92
93 /* backup registers */
94 swap->pdar_backup = ddb_in32(swap->pdar);
95 swap->pmr_backup = ddb_in32(swap->pmr);
96
97 /* set the pdar (pci window) register */
98 ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32, /* 32 bit wide */
99 0, /* not on local memory bus */
100 0); /* not visible from PCI bus (N/A) */
101
102 /*
103 * calcuate the absolute pci config addr;
104 * according to the spec, we start scanning from adr:11 (0x800)
105 */
106 if (bus == 0) {
107 /* type 0 config */
108 pci_addr = 0x800 << slot_num;
109 } else {
110 /* type 1 config */
111 pci_addr = (bus << 16) | (slot_num << 11);
112 /* panic("ddb_access_config_base: we don't support type 1 config Yet"); */
113 }
114
115 /*
116 * if pci_addr is less than pci config window size, we set
117 * pciinit_offset to 0 and adjust the virt_address.
118 * Otherwise we will try to adjust pciinit_offset.
119 */
120 if (pci_addr < swap->config_size) {
121 virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
122 pciinit_offset = 0;
123 } else {
124 db_assert((pci_addr & (swap->config_size - 1)) == 0);
125 virt_addr = KSEG1ADDR(swap->config_base);
126 pciinit_offset = pci_addr;
127 }
128
129 /* set the pmr register */
130 option = DDB_PCI_ACCESS_32;
131 if (bus != 0)
132 option |= DDB_PCI_CFGTYPE1;
133 ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
134
135 return virt_addr;
136}
137
138static inline void ddb_close_config_base(struct pci_config_swap *swap)
139{
140 ddb_out32(swap->pdar, swap->pdar_backup);
141 ddb_out32(swap->pmr, swap->pmr_backup);
142}
143
144static int read_config_dword(struct pci_config_swap *swap,
145 struct pci_dev *dev, u32 where, u32 * val)
146{
147 u32 bus, slot_num, func_num;
148 u32 base;
149
150 db_assert((where & 3) == 0);
151 db_assert(where < (1 << 8));
152
153 /* check if the bus is top-level */
154 if (dev->bus->parent != NULL) {
155 bus = dev->bus->number;
156 db_assert(bus != 0);
157 } else {
158 bus = 0;
159 }
160
161 slot_num = PCI_SLOT(dev->devfn);
162 func_num = PCI_FUNC(dev->devfn);
163 base = ddb_access_config_base(swap, bus, slot_num);
164 *val = *(volatile u32 *) (base + (func_num << 8) + where);
165 ddb_close_config_base(swap);
166 return PCIBIOS_SUCCESSFUL;
167}
168
169static int read_config_word(struct pci_config_swap *swap,
170 struct pci_dev *dev, u32 where, u16 * val)
171{
172 int status;
173 u32 result;
174
175 db_assert((where & 1) == 0);
176
177 status = read_config_dword(swap, dev, where & ~3, &result);
178 if (where & 2)
179 result >>= 16;
180 *val = result & 0xffff;
181 return status;
182}
183
184static int read_config_byte(struct pci_config_swap *swap,
185 struct pci_dev *dev, u32 where, u8 * val)
186{
187 int status;
188 u32 result;
189
190 status = read_config_dword(swap, dev, where & ~3, &result);
191 if (where & 1)
192 result >>= 8;
193 if (where & 2)
194 result >>= 16;
195 *val = result & 0xff;
196 return status;
197}
198
199static int write_config_dword(struct pci_config_swap *swap,
200 struct pci_dev *dev, u32 where, u32 val)
201{
202 u32 bus, slot_num, func_num;
203 u32 base;
204
205 db_assert((where & 3) == 0);
206 db_assert(where < (1 << 8));
207
208 /* check if the bus is top-level */
209 if (dev->bus->parent != NULL) {
210 bus = dev->bus->number;
211 db_assert(bus != 0);
212 } else {
213 bus = 0;
214 }
215
216 slot_num = PCI_SLOT(dev->devfn);
217 func_num = PCI_FUNC(dev->devfn);
218 base = ddb_access_config_base(swap, bus, slot_num);
219 *(volatile u32 *) (base + (func_num << 8) + where) = val;
220 ddb_close_config_base(swap);
221 return PCIBIOS_SUCCESSFUL;
222}
223
224static int write_config_word(struct pci_config_swap *swap,
225 struct pci_dev *dev, u32 where, u16 val)
226{
227 int status, shift = 0;
228 u32 result;
229
230 db_assert((where & 1) == 0);
231
232 status = read_config_dword(swap, dev, where & ~3, &result);
233 if (status != PCIBIOS_SUCCESSFUL)
234 return status;
235
236 if (where & 2)
237 shift += 16;
238 result &= ~(0xffff << shift);
239 result |= val << shift;
240 return write_config_dword(swap, dev, where & ~3, result);
241}
242
243static int write_config_byte(struct pci_config_swap *swap,
244 struct pci_dev *dev, u32 where, u8 val)
245{
246 int status, shift = 0;
247 u32 result;
248
249 status = read_config_dword(swap, dev, where & ~3, &result);
250 if (status != PCIBIOS_SUCCESSFUL)
251 return status;
252
253 if (where & 2)
254 shift += 16;
255 if (where & 1)
256 shift += 8;
257 result &= ~(0xff << shift);
258 result |= val << shift;
259 return write_config_dword(swap, dev, where & ~3, result);
260}
261
262#define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \
263static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \
264{ \
265 return rw##_config_##unitname(pciswap, \
266 dev, \
267 where, \
268 val); \
269}
270
271MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap)
272 MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap)
273 MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap)
274
275 MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap)
276 MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap)
277 MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap)
278
279struct pci_ops ddb5476_ext_pci_ops = {
280 extpci_read_config_byte,
281 extpci_read_config_word,
282 extpci_read_config_dword,
283 extpci_write_config_byte,
284 extpci_write_config_word,
285 extpci_write_config_dword
286};
diff --git a/arch/mips/pci/ops-ddb5477.c b/arch/mips/pci/ops-ddb5477.c
new file mode 100644
index 00000000000..e955443fedf
--- /dev/null
+++ b/arch/mips/pci/ops-ddb5477.c
@@ -0,0 +1,278 @@
1/***********************************************************************
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 *
5 * arch/mips/ddb5xxx/ddb5477/pci_ops.c
6 * Define the pci_ops for DB5477.
7 *
8 * Much of the code is derived from the original DDB5074 port by
9 * Geert Uytterhoeven <geert@sonycom.com>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 ***********************************************************************
16 */
17
18/*
19 * DDB5477 has two PCI channels, external PCI and IOPIC (internal)
20 * Therefore we provide two sets of pci_ops.
21 */
22#include <linux/pci.h>
23#include <linux/kernel.h>
24#include <linux/types.h>
25
26#include <asm/addrspace.h>
27#include <asm/debug.h>
28
29#include <asm/ddb5xxx/ddb5xxx.h>
30
31/*
32 * config_swap structure records what set of pdar/pmr are used
33 * to access pci config space. It also provides a place hold the
34 * original values for future restoring.
35 */
36struct pci_config_swap {
37 u32 pdar;
38 u32 pmr;
39 u32 config_base;
40 u32 config_size;
41 u32 pdar_backup;
42 u32 pmr_backup;
43};
44
45/*
46 * On DDB5477, we have two sets of swap registers, for ext PCI and IOPCI.
47 */
48struct pci_config_swap ext_pci_swap = {
49 DDB_PCIW0,
50 DDB_PCIINIT00,
51 DDB_PCI0_CONFIG_BASE,
52 DDB_PCI0_CONFIG_SIZE
53};
54struct pci_config_swap io_pci_swap = {
55 DDB_IOPCIW0,
56 DDB_PCIINIT01,
57 DDB_PCI1_CONFIG_BASE,
58 DDB_PCI1_CONFIG_SIZE
59};
60
61
62/*
63 * access config space
64 */
65static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus, /* 0 means top level bus */
66 u32 slot_num)
67{
68 u32 pci_addr = 0;
69 u32 pciinit_offset = 0;
70 u32 virt_addr;
71 u32 option;
72
73 /* minimum pdar (window) size is 2MB */
74 db_assert(swap->config_size >= (2 << 20));
75
76 db_assert(slot_num < (1 << 5));
77 db_assert(bus < (1 << 8));
78
79 /* backup registers */
80 swap->pdar_backup = ddb_in32(swap->pdar);
81 swap->pmr_backup = ddb_in32(swap->pmr);
82
83 /* set the pdar (pci window) register */
84 ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32, /* 32 bit wide */
85 0, /* not on local memory bus */
86 0); /* not visible from PCI bus (N/A) */
87
88 /*
89 * calcuate the absolute pci config addr;
90 * according to the spec, we start scanning from adr:11 (0x800)
91 */
92 if (bus == 0) {
93 /* type 0 config */
94 pci_addr = 0x800 << slot_num;
95 } else {
96 /* type 1 config */
97 pci_addr = (bus << 16) | (slot_num << 11);
98 }
99
100 /*
101 * if pci_addr is less than pci config window size, we set
102 * pciinit_offset to 0 and adjust the virt_address.
103 * Otherwise we will try to adjust pciinit_offset.
104 */
105 if (pci_addr < swap->config_size) {
106 virt_addr = KSEG1ADDR(swap->config_base + pci_addr);
107 pciinit_offset = 0;
108 } else {
109 db_assert((pci_addr & (swap->config_size - 1)) == 0);
110 virt_addr = KSEG1ADDR(swap->config_base);
111 pciinit_offset = pci_addr;
112 }
113
114 /* set the pmr register */
115 option = DDB_PCI_ACCESS_32;
116 if (bus != 0)
117 option |= DDB_PCI_CFGTYPE1;
118 ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option);
119
120 return virt_addr;
121}
122
123static inline void ddb_close_config_base(struct pci_config_swap *swap)
124{
125 ddb_out32(swap->pdar, swap->pdar_backup);
126 ddb_out32(swap->pmr, swap->pmr_backup);
127}
128
129static int read_config_dword(struct pci_config_swap *swap,
130 struct pci_bus *bus, u32 devfn, u32 where,
131 u32 * val)
132{
133 u32 bus_num, slot_num, func_num;
134 u32 base;
135
136 db_assert((where & 3) == 0);
137 db_assert(where < (1 << 8));
138
139 /* check if the bus is top-level */
140 if (bus->parent != NULL) {
141 bus_num = bus->number;
142 db_assert(bus_num != 0);
143 } else {
144 bus_num = 0;
145 }
146
147 slot_num = PCI_SLOT(devfn);
148 func_num = PCI_FUNC(devfn);
149 base = ddb_access_config_base(swap, bus_num, slot_num);
150 *val = *(volatile u32 *) (base + (func_num << 8) + where);
151 ddb_close_config_base(swap);
152 return PCIBIOS_SUCCESSFUL;
153}
154
155static int read_config_word(struct pci_config_swap *swap,
156 struct pci_bus *bus, u32 devfn, u32 where,
157 u16 * val)
158{
159 int status;
160 u32 result;
161
162 db_assert((where & 1) == 0);
163
164 status = read_config_dword(swap, bus, devfn, where & ~3, &result);
165 if (where & 2)
166 result >>= 16;
167 *val = result & 0xffff;
168 return status;
169}
170
171static int read_config_byte(struct pci_config_swap *swap,
172 struct pci_bus *bus, u32 devfn, u32 where,
173 u8 * val)
174{
175 int status;
176 u32 result;
177
178 status = read_config_dword(swap, bus, devfn, where & ~3, &result);
179 if (where & 1)
180 result >>= 8;
181 if (where & 2)
182 result >>= 16;
183 *val = result & 0xff;
184
185 return status;
186}
187
188static int write_config_dword(struct pci_config_swap *swap,
189 struct pci_bus *bus, u32 devfn, u32 where,
190 u32 val)
191{
192 u32 bus_num, slot_num, func_num;
193 u32 base;
194
195 db_assert((where & 3) == 0);
196 db_assert(where < (1 << 8));
197
198 /* check if the bus is top-level */
199 if (bus->parent != NULL) {
200 bus_num = bus->number;
201 db_assert(bus_num != 0);
202 } else {
203 bus_num = 0;
204 }
205
206 slot_num = PCI_SLOT(devfn);
207 func_num = PCI_FUNC(devfn);
208 base = ddb_access_config_base(swap, bus_num, slot_num);
209 *(volatile u32 *) (base + (func_num << 8) + where) = val;
210 ddb_close_config_base(swap);
211 return PCIBIOS_SUCCESSFUL;
212}
213
214static int write_config_word(struct pci_config_swap *swap,
215 struct pci_bus *bus, u32 devfn, u32 where, u16 val)
216{
217 int status, shift = 0;
218 u32 result;
219
220 db_assert((where & 1) == 0);
221
222 status = read_config_dword(swap, bus, devfn, where & ~3, &result);
223 if (status != PCIBIOS_SUCCESSFUL)
224 return status;
225
226 if (where & 2)
227 shift += 16;
228 result &= ~(0xffff << shift);
229 result |= val << shift;
230 return write_config_dword(swap, bus, devfn, where & ~3, result);
231}
232
233static int write_config_byte(struct pci_config_swap *swap,
234 struct pci_bus *bus, u32 devfn, u32 where, u8 val)
235{
236 int status, shift = 0;
237 u32 result;
238
239 status = read_config_dword(swap, bus, devfn, where & ~3, &result);
240 if (status != PCIBIOS_SUCCESSFUL)
241 return status;
242
243 if (where & 2)
244 shift += 16;
245 if (where & 1)
246 shift += 8;
247 result &= ~(0xff << shift);
248 result |= val << shift;
249 return write_config_dword(swap, bus, devfn, where & ~3, result);
250}
251
252#define MAKE_PCI_OPS(prefix, rw, pciswap, star) \
253static int prefix##_##rw##_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 star val) \
254{ \
255 if (size == 1) \
256 return rw##_config_byte(pciswap, bus, devfn, where, (u8 star)val); \
257 else if (size == 2) \
258 return rw##_config_word(pciswap, bus, devfn, where, (u16 star)val); \
259 /* Size must be 4 */ \
260 return rw##_config_dword(pciswap, bus, devfn, where, val); \
261}
262
263MAKE_PCI_OPS(extpci, read, &ext_pci_swap, *)
264MAKE_PCI_OPS(extpci, write, &ext_pci_swap,)
265
266MAKE_PCI_OPS(iopci, read, &io_pci_swap, *)
267MAKE_PCI_OPS(iopci, write, &io_pci_swap,)
268
269struct pci_ops ddb5477_ext_pci_ops = {
270 .read = extpci_read_config,
271 .write = extpci_write_config
272};
273
274
275struct pci_ops ddb5477_io_pci_ops = {
276 .read = iopci_read_config,
277 .write = iopci_write_config
278};
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c
new file mode 100644
index 00000000000..c5b0fc184c2
--- /dev/null
+++ b/arch/mips/pci/ops-gt64111.c
@@ -0,0 +1,100 @@
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) 1995, 1996, 1997, 2002 by Ralf Baechle
7 * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
8 */
9#include <linux/types.h>
10#include <linux/pci.h>
11#include <linux/kernel.h>
12#include <linux/init.h>
13
14#include <asm/pci.h>
15#include <asm/io.h>
16#include <asm/gt64120.h>
17
18#include <asm/cobalt/cobalt.h>
19
20/*
21 * Accessing device 31 hangs the GT64120. Not sure if this will also hang
22 * the GT64111, let's be paranoid for now.
23 */
24static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
25{
26 if (bus->number == 0 && devfn == PCI_DEVFN(31, 0))
27 return -1;
28
29 return 0;
30}
31
32static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn,
33 int where, int size, u32 * val)
34{
35 if (pci_range_ck(bus, devfn))
36 return PCIBIOS_DEVICE_NOT_FOUND;
37
38 switch (size) {
39 case 4:
40 PCI_CFG_SET(devfn, where);
41 *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS);
42 return PCIBIOS_SUCCESSFUL;
43
44 case 2:
45 PCI_CFG_SET(devfn, (where & ~0x3));
46 *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS)
47 >> ((where & 3) * 8);
48 return PCIBIOS_SUCCESSFUL;
49
50 case 1:
51 PCI_CFG_SET(devfn, (where & ~0x3));
52 *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS)
53 >> ((where & 3) * 8);
54 return PCIBIOS_SUCCESSFUL;
55 }
56
57 return PCIBIOS_BAD_REGISTER_NUMBER;
58}
59
60static int gt64111_pci_write_config(struct pci_bus *bus, unsigned int devfn,
61 int where, int size, u32 val)
62{
63 u32 tmp;
64
65 if (pci_range_ck(bus, devfn))
66 return PCIBIOS_DEVICE_NOT_FOUND;
67
68 switch (size) {
69 case 4:
70 PCI_CFG_SET(devfn, where);
71 GALILEO_OUTL(val, GT_PCI0_CFGDATA_OFS);
72
73 return PCIBIOS_SUCCESSFUL;
74
75 case 2:
76 PCI_CFG_SET(devfn, (where & ~0x3));
77 tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS);
78 tmp &= ~(0xffff << ((where & 0x3) * 8));
79 tmp |= (val << ((where & 0x3) * 8));
80 GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS);
81
82 return PCIBIOS_SUCCESSFUL;
83
84 case 1:
85 PCI_CFG_SET(devfn, (where & ~0x3));
86 tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS);
87 tmp &= ~(0xff << ((where & 0x3) * 8));
88 tmp |= (val << ((where & 0x3) * 8));
89 GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS);
90
91 return PCIBIOS_SUCCESSFUL;
92 }
93
94 return PCIBIOS_BAD_REGISTER_NUMBER;
95}
96
97struct pci_ops gt64111_pci_ops = {
98 .read = gt64111_pci_read_config,
99 .write = gt64111_pci_write_config,
100};
diff --git a/arch/mips/pci/ops-gt64120.c b/arch/mips/pci/ops-gt64120.c
new file mode 100644
index 00000000000..7b99dfa33df
--- /dev/null
+++ b/arch/mips/pci/ops-gt64120.c
@@ -0,0 +1,154 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 */
18#include <linux/types.h>
19#include <linux/pci.h>
20#include <linux/kernel.h>
21
22#include <asm/gt64120.h>
23
24#define PCI_ACCESS_READ 0
25#define PCI_ACCESS_WRITE 1
26
27/*
28 * PCI configuration cycle AD bus definition
29 */
30/* Type 0 */
31#define PCI_CFG_TYPE0_REG_SHF 0
32#define PCI_CFG_TYPE0_FUNC_SHF 8
33
34/* Type 1 */
35#define PCI_CFG_TYPE1_REG_SHF 0
36#define PCI_CFG_TYPE1_FUNC_SHF 8
37#define PCI_CFG_TYPE1_DEV_SHF 11
38#define PCI_CFG_TYPE1_BUS_SHF 16
39
40static int gt64120_pcibios_config_access(unsigned char access_type,
41 struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
42{
43 unsigned char busnum = bus->number;
44 u32 intr;
45
46 if ((busnum == 0) && (PCI_SLOT(devfn) == 0))
47 /* Galileo itself is devfn 0, don't move it around */
48 return -1;
49
50 if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
51 return -1; /* Because of a bug in the galileo (for slot 31). */
52
53 /* Clear cause register bits */
54 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
55 GT_INTRCAUSE_TARABORT0_BIT));
56
57 /* Setup address */
58 GT_WRITE(GT_PCI0_CFGADDR_OFS,
59 (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) |
60 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
61 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
62 GT_PCI0_CFGADDR_CONFIGEN_BIT);
63
64 if (access_type == PCI_ACCESS_WRITE) {
65 if (busnum == 0 && PCI_SLOT(devfn) == 0) {
66 /*
67 * The Galileo system controller is acting
68 * differently than other devices.
69 */
70 GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
71 } else
72 __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
73 } else {
74 if (busnum == 0 && PCI_SLOT(devfn) == 0) {
75 /*
76 * The Galileo system controller is acting
77 * differently than other devices.
78 */
79 *data = GT_READ(GT_PCI0_CFGDATA_OFS);
80 } else
81 *data = __GT_READ(GT_PCI0_CFGDATA_OFS);
82 }
83
84 /* Check for master or target abort */
85 intr = GT_READ(GT_INTRCAUSE_OFS);
86
87 if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
88 /* Error occurred */
89
90 /* Clear bits */
91 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
92 GT_INTRCAUSE_TARABORT0_BIT));
93
94 return -1;
95 }
96
97 return 0;
98}
99
100
101/*
102 * We can't address 8 and 16 bit words directly. Instead we have to
103 * read/write a 32bit word and mask/modify the data we actually want.
104 */
105static int gt64120_pcibios_read(struct pci_bus *bus, unsigned int devfn,
106 int where, int size, u32 * val)
107{
108 u32 data = 0;
109
110 if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
111 &data))
112 return PCIBIOS_DEVICE_NOT_FOUND;
113
114 if (size == 1)
115 *val = (data >> ((where & 3) << 3)) & 0xff;
116 else if (size == 2)
117 *val = (data >> ((where & 3) << 3)) & 0xffff;
118 else
119 *val = data;
120
121 return PCIBIOS_SUCCESSFUL;
122}
123
124static int gt64120_pcibios_write(struct pci_bus *bus, unsigned int devfn,
125 int where, int size, u32 val)
126{
127 u32 data = 0;
128
129 if (size == 4)
130 data = val;
131 else {
132 if (gt64120_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
133 where, &data))
134 return PCIBIOS_DEVICE_NOT_FOUND;
135
136 if (size == 1)
137 data = (data & ~(0xff << ((where & 3) << 3))) |
138 (val << ((where & 3) << 3));
139 else if (size == 2)
140 data = (data & ~(0xffff << ((where & 3) << 3))) |
141 (val << ((where & 3) << 3));
142 }
143
144 if (gt64120_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
145 &data))
146 return PCIBIOS_DEVICE_NOT_FOUND;
147
148 return PCIBIOS_SUCCESSFUL;
149}
150
151struct pci_ops gt64120_pci_ops = {
152 .read = gt64120_pcibios_read,
153 .write = gt64120_pcibios_write
154};
diff --git a/arch/mips/pci/ops-gt96100.c b/arch/mips/pci/ops-gt96100.c
new file mode 100644
index 00000000000..9e4ea6627e2
--- /dev/null
+++ b/arch/mips/pci/ops-gt96100.c
@@ -0,0 +1,169 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * Galileo EV96100 board specific pci support.
5 *
6 * Copyright 2000 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
9 *
10 * This file was derived from Carsten Langgaard's
11 * arch/mips/mips-boards/generic/pci.c
12 *
13 * Carsten Langgaard, carstenl@mips.com
14 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
24 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * You should have received a copy of the GNU General Public License along
33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36#include <linux/types.h>
37#include <linux/pci.h>
38#include <linux/kernel.h>
39#include <linux/init.h>
40
41#include <asm/delay.h>
42#include <asm/gt64120.h>
43#include <asm/galileo-boards/ev96100.h>
44
45#define PCI_ACCESS_READ 0
46#define PCI_ACCESS_WRITE 1
47
48static int static gt96100_config_access(unsigned char access_type,
49 struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
50{
51 unsigned char bus = bus->number;
52 u32 intr;
53
54 /*
55 * Because of a bug in the galileo (for slot 31).
56 */
57 if (bus == 0 && devfn >= PCI_DEVFN(31, 0))
58 return PCIBIOS_DEVICE_NOT_FOUND;
59
60 /* Clear cause register bits */
61 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
62 GT_INTRCAUSE_TARABORT0_BIT));
63
64 /* Setup address */
65 GT_WRITE(GT_PCI0_CFGADDR_OFS,
66 (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) |
67 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
68 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
69 GT_PCI0_CFGADDR_CONFIGEN_BIT);
70 udelay(2);
71
72
73 if (access_type == PCI_ACCESS_WRITE) {
74 if (devfn != 0)
75 *data = le32_to_cpu(*data);
76 GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
77 } else {
78 *data = GT_READ(GT_PCI0_CFGDATA_OFS);
79 if (devfn != 0)
80 *data = le32_to_cpu(*data);
81 }
82
83 udelay(2);
84
85 /* Check for master or target abort */
86 intr = GT_READ(GT_INTRCAUSE_OFS);
87
88 if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
89 /* Error occured */
90
91 /* Clear bits */
92 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
93 GT_INTRCAUSE_TARABORT0_BIT));
94 return -1;
95 }
96 return 0;
97}
98
99/*
100 * We can't address 8 and 16 bit words directly. Instead we have to
101 * read/write a 32bit word and mask/modify the data we actually want.
102 */
103static int gt96100_pcibios_read(struct pci_bus *bus, unsigned int devfn,
104 int where, int size, u32 * val)
105{
106 u32 data = 0;
107
108 if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
109 return PCIBIOS_DEVICE_NOT_FOUND;
110
111 switch (size) {
112 case 1:
113 *val = (data >> ((where & 3) << 3)) & 0xff;
114 break;
115
116 case 2:
117 *val = (data >> ((where & 3) << 3)) & 0xffff;
118 break;
119
120 case 4:
121 *val = data;
122 break;
123 }
124 return PCIBIOS_SUCCESSFUL;
125}
126
127static int gt96100_pcibios_write(struct pci_bus *bus, unsigned int devfn,
128 int where, int size, u32 val)
129{
130 u32 data = 0;
131
132 switch (size) {
133 case 1:
134 if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
135 return -1;
136
137 data = (data & ~(0xff << ((where & 3) << 3))) |
138 (val << ((where & 3) << 3));
139
140 if (gt96100_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
141 return -1;
142
143 return PCIBIOS_SUCCESSFUL;
144
145 case 2:
146 if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
147 return -1;
148
149 data = (data & ~(0xffff << ((where & 3) << 3))) |
150 (val << ((where & 3) << 3));
151
152 if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
153 return -1;
154
155
156 return PCIBIOS_SUCCESSFUL;
157
158 case 4:
159 if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val))
160 return -1;
161
162 return PCIBIOS_SUCCESSFUL;
163 }
164}
165
166struct pci_ops gt96100_pci_ops = {
167 .read = gt96100_pcibios_read,
168 .write = gt96100_pcibios_write
169};
diff --git a/arch/mips/pci/ops-it8172.c b/arch/mips/pci/ops-it8172.c
new file mode 100644
index 00000000000..b7a8b9a6f9d
--- /dev/null
+++ b/arch/mips/pci/ops-it8172.c
@@ -0,0 +1,215 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * IT8172 system controller specific pci support.
5 *
6 * Copyright 2000 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
9 *
10 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32#include <linux/types.h>
33#include <linux/pci.h>
34#include <linux/kernel.h>
35#include <linux/init.h>
36
37#include <asm/it8172/it8172.h>
38#include <asm/it8172/it8172_pci.h>
39
40#define PCI_ACCESS_READ 0
41#define PCI_ACCESS_WRITE 1
42
43#undef DEBUG
44#ifdef DEBUG
45#define DBG(x...) printk(x)
46#else
47#define DBG(x...)
48#endif
49
50static struct resource pci_mem_resource_1;
51
52static struct resource pci_io_resource = {
53 "io pci IO space",
54 0x14018000,
55 0x17FFFFFF,
56 IORESOURCE_IO
57};
58
59static struct resource pci_mem_resource_0 = {
60 "ext pci memory space 0/1",
61 0x10101000,
62 0x13FFFFFF,
63 IORESOURCE_MEM,
64 &pci_mem_resource_0,
65 NULL,
66 &pci_mem_resource_1
67};
68
69static struct resource pci_mem_resource_1 = {
70 "ext pci memory space 2/3",
71 0x1A000000,
72 0x1FBFFFFF,
73 IORESOURCE_MEM,
74 &pci_mem_resource_0,
75 NULL,
76 NULL
77};
78
79extern struct pci_ops it8172_pci_ops;
80
81struct pci_controller it8172_controller = {
82 .pci_ops = &it8172_pci_ops,
83 .io_resource = &pci_io_resource,
84 .mem_resource = &pci_mem_resource_0,
85};
86
87static int it8172_pcibios_config_access(unsigned char access_type,
88 struct pci_bus *bus,
89 unsigned int devfn, int where,
90 u32 * data)
91{
92 /*
93 * config cycles are on 4 byte boundary only
94 */
95
96 /* Setup address */
97 IT_WRITE(IT_CONFADDR, (bus->number << IT_BUSNUM_SHF) |
98 (devfn << IT_FUNCNUM_SHF) | (where & ~0x3));
99
100 if (access_type == PCI_ACCESS_WRITE) {
101 IT_WRITE(IT_CONFDATA, *data);
102 } else {
103 IT_READ(IT_CONFDATA, *data);
104 }
105
106 /*
107 * Revisit: check for master or target abort.
108 */
109 return 0;
110}
111
112
113/*
114 * We can't address 8 and 16 bit words directly. Instead we have to
115 * read/write a 32bit word and mask/modify the data we actually want.
116 */
117static write_config(struct pci_bus *bus, unsigned int devfn, int where,
118 int size, u32 val)
119{
120 u32 data = 0;
121
122 switch (size) {
123 case 1:
124 if (it8172_pcibios_config_access
125 (PCI_ACCESS_READ, dev, where, &data))
126 return -1;
127
128 *val = (data >> ((where & 3) << 3)) & 0xff;
129
130 return PCIBIOS_SUCCESSFUL;
131
132 case 2:
133
134 if (where & 1)
135 return PCIBIOS_BAD_REGISTER_NUMBER;
136
137 if (it8172_pcibios_config_access
138 (PCI_ACCESS_READ, dev, where, &data))
139 return -1;
140
141 *val = (data >> ((where & 3) << 3)) & 0xffff;
142 DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n",
143 dev->bus->number, dev->devfn, where, *val);
144
145 return PCIBIOS_SUCCESSFUL;
146
147 case 4:
148
149 if (where & 3)
150 return PCIBIOS_BAD_REGISTER_NUMBER;
151
152 if (it8172_pcibios_config_access
153 (PCI_ACCESS_READ, dev, where, &data))
154 return -1;
155
156 *val = data;
157
158 return PCIBIOS_SUCCESSFUL;
159 }
160}
161
162
163static write_config(struct pci_bus *bus, unsigned int devfn, int where,
164 int size, u32 val)
165{
166 u32 data = 0;
167
168 switch (size) {
169 case 1:
170 if (it8172_pcibios_config_access
171 (PCI_ACCESS_READ, dev, where, &data))
172 return -1;
173
174 data = (data & ~(0xff << ((where & 3) << 3))) |
175 (val << ((where & 3) << 3));
176
177 if (it8172_pcibios_config_access
178 (PCI_ACCESS_WRITE, dev, where, &data))
179 return -1;
180
181 return PCIBIOS_SUCCESSFUL;
182
183 case 2:
184 if (where & 1)
185 return PCIBIOS_BAD_REGISTER_NUMBER;
186
187 if (it8172_pcibios_config_access
188 (PCI_ACCESS_READ, dev, where, &data))
189 eturn - 1;
190
191 data = (data & ~(0xffff << ((where & 3) << 3))) |
192 (val << ((where & 3) << 3));
193
194 if (it8172_pcibios_config_access
195 (PCI_ACCESS_WRITE, dev, where, &data))
196 return -1;
197
198 return PCIBIOS_SUCCESSFUL;
199
200 case 4:
201 if (where & 3)
202 return PCIBIOS_BAD_REGISTER_NUMBER;
203
204 if (it8172_pcibios_config_access
205 (PCI_ACCESS_WRITE, dev, where, &val))
206 return -1;
207
208 return PCIBIOS_SUCCESSFUL;
209 }
210}
211
212struct pci_ops it8172_pci_ops = {
213 .read = read_config,
214 .write = write_config,
215};
diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c
new file mode 100644
index 00000000000..8008e31c5e8
--- /dev/null
+++ b/arch/mips/pci/ops-mace.c
@@ -0,0 +1,91 @@
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 */
8#include <linux/kernel.h>
9#include <linux/init.h>
10#include <linux/pci.h>
11#include <linux/types.h>
12#include <asm/pci.h>
13#include <asm/ip32/mace.h>
14
15#if 0
16# define DPRINTK(args...) printk(args);
17#else
18# define DPRINTK(args...)
19#endif
20
21/*
22 * O2 has up to 5 PCI devices connected into the MACE bridge. The device
23 * map looks like this:
24 *
25 * 0 aic7xxx 0
26 * 1 aic7xxx 1
27 * 2 expansion slot
28 * 3 N/C
29 * 4 N/C
30 */
31
32#define chkslot(_bus,_devfn) \
33do { \
34 if ((_bus)->number > 0 || PCI_SLOT (_devfn) < 1 \
35 || PCI_SLOT (_devfn) > 3) \
36 return PCIBIOS_DEVICE_NOT_FOUND; \
37} while (0)
38
39#define mkaddr(_devfn, _reg) \
40((((_devfn) & 0xffUL) << 8) | ((_reg) & 0xfcUL))
41
42static int
43mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
44 int reg, int size, u32 *val)
45{
46 chkslot(bus, devfn);
47 mace->pci.config_addr = mkaddr(devfn, reg);
48 switch (size) {
49 case 1:
50 *val = mace->pci.config_data.b[(reg & 3) ^ 3];
51 break;
52 case 2:
53 *val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
54 break;
55 case 4:
56 *val = mace->pci.config_data.l;
57 break;
58 }
59
60 DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
61
62 return PCIBIOS_SUCCESSFUL;
63}
64
65static int
66mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
67 int reg, int size, u32 val)
68{
69 chkslot(bus, devfn);
70 mace->pci.config_addr = mkaddr(devfn, reg);
71 switch (size) {
72 case 1:
73 mace->pci.config_data.b[(reg & 3) ^ 3] = val;
74 break;
75 case 2:
76 mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
77 break;
78 case 4:
79 mace->pci.config_data.l = val;
80 break;
81 }
82
83 DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
84
85 return PCIBIOS_SUCCESSFUL;
86}
87
88struct pci_ops mace_pci_ops = {
89 .read = mace_pci_read_config,
90 .write = mace_pci_write_config,
91};
diff --git a/arch/mips/pci/ops-marvell.c b/arch/mips/pci/ops-marvell.c
new file mode 100644
index 00000000000..1ac5c59199d
--- /dev/null
+++ b/arch/mips/pci/ops-marvell.c
@@ -0,0 +1,93 @@
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) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
7 */
8#include <linux/kernel.h>
9#include <linux/types.h>
10#include <linux/pci.h>
11
12#include <asm/marvell.h>
13
14static int mv_read_config(struct pci_bus *bus, unsigned int devfn,
15 int where, int size, u32 * val)
16{
17 struct mv_pci_controller *mvbc = bus->sysdata;
18 unsigned long address_reg, data_reg;
19 u32 address;
20
21 address_reg = mvbc->config_addr;
22 data_reg = mvbc->config_vreg;
23
24 /* Accessing device 31 crashes those Marvells. Since years.
25 Will they ever make sane controllers ... */
26 if (PCI_SLOT(devfn) == 31)
27 return PCIBIOS_DEVICE_NOT_FOUND;
28
29 address = (bus->number << 16) | (devfn << 8) |
30 (where & 0xfc) | 0x80000000;
31
32 /* start the configuration cycle */
33 MV_WRITE(address_reg, address);
34
35 switch (size) {
36 case 1:
37 *val = MV_READ_8(data_reg + (where & 0x3));
38 break;
39
40 case 2:
41 *val = MV_READ_16(data_reg + (where & 0x3));
42 break;
43
44 case 4:
45 *val = MV_READ(data_reg);
46 break;
47 }
48
49 return PCIBIOS_SUCCESSFUL;
50}
51
52static int mv_write_config(struct pci_bus *bus, unsigned int devfn,
53 int where, int size, u32 val)
54{
55 struct mv_pci_controller *mvbc = bus->sysdata;
56 unsigned long address_reg, data_reg;
57 u32 address;
58
59 address_reg = mvbc->config_addr;
60 data_reg = mvbc->config_vreg;
61
62 /* Accessing device 31 crashes those Marvells. Since years.
63 Will they ever make sane controllers ... */
64 if (PCI_SLOT(devfn) == 31)
65 return PCIBIOS_DEVICE_NOT_FOUND;
66
67 address = (bus->number << 16) | (devfn << 8) |
68 (where & 0xfc) | 0x80000000;
69
70 /* start the configuration cycle */
71 MV_WRITE(address_reg, address);
72
73 switch (size) {
74 case 1:
75 MV_WRITE_8(data_reg + (where & 0x3), val);
76 break;
77
78 case 2:
79 MV_WRITE_16(data_reg + (where & 0x3), val);
80 break;
81
82 case 4:
83 MV_WRITE(data_reg, val);
84 break;
85 }
86
87 return PCIBIOS_SUCCESSFUL;
88}
89
90struct pci_ops mv_pci_ops = {
91 .read = mv_read_config,
92 .write = mv_write_config
93};
diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c
new file mode 100644
index 00000000000..7bc099643a9
--- /dev/null
+++ b/arch/mips/pci/ops-msc.c
@@ -0,0 +1,169 @@
1/*
2 * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
3 * All rights reserved.
4 * Authors: Carsten Langgaard <carstenl@mips.com>
5 * Maciej W. Rozycki <macro@mips.com>
6 * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
7 *
8 * This program is free software; you can distribute it and/or modify it
9 * under the terms of the GNU General Public License (Version 2) as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
20 *
21 * MIPS boards specific PCI support.
22 *
23 */
24#include <linux/config.h>
25#include <linux/types.h>
26#include <linux/pci.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29
30#include <asm/mips-boards/msc01_pci.h>
31
32#define PCI_ACCESS_READ 0
33#define PCI_ACCESS_WRITE 1
34
35/*
36 * PCI configuration cycle AD bus definition
37 */
38/* Type 0 */
39#define PCI_CFG_TYPE0_REG_SHF 0
40#define PCI_CFG_TYPE0_FUNC_SHF 8
41
42/* Type 1 */
43#define PCI_CFG_TYPE1_REG_SHF 0
44#define PCI_CFG_TYPE1_FUNC_SHF 8
45#define PCI_CFG_TYPE1_DEV_SHF 11
46#define PCI_CFG_TYPE1_BUS_SHF 16
47
48static int msc_pcibios_config_access(unsigned char access_type,
49 struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
50{
51 unsigned char busnum = bus->number;
52 unsigned char type;
53 u32 intr;
54
55#ifdef CONFIG_MIPS_BOARDS_GEN
56 if ((busnum == 0) && (PCI_SLOT(devfn) == 17)) {
57 /* MIPS Core boards have SOCit connected as device 17 */
58 return -1;
59 }
60#endif
61
62 /* Clear status register bits. */
63 MSC_WRITE(MSC01_PCI_INTSTAT,
64 (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
65
66 /* Setup address */
67 if (busnum == 0)
68 type = 0; /* Type 0 */
69 else
70 type = 1; /* Type 1 */
71
72 MSC_WRITE(MSC01_PCI_CFGADDR,
73 ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
74 (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF)
75 | (PCI_FUNC(devfn) <<
76 MSC01_PCI_CFGADDR_FNUM_SHF) | ((where /
77 4) <<
78 MSC01_PCI_CFGADDR_RNUM_SHF)
79 | (type)));
80
81 /* Perform access */
82 if (access_type == PCI_ACCESS_WRITE)
83 MSC_WRITE(MSC01_PCI_CFGDATA, *data);
84 else
85 MSC_READ(MSC01_PCI_CFGDATA, *data);
86
87 /* Detect Master/Target abort */
88 MSC_READ(MSC01_PCI_INTSTAT, intr);
89 if (intr & (MSC01_PCI_INTCFG_MA_BIT |
90 MSC01_PCI_INTCFG_TA_BIT)) {
91 /* Error occurred */
92
93 /* Clear bits */
94 MSC_READ(MSC01_PCI_INTSTAT, intr);
95 MSC_WRITE(MSC01_PCI_INTSTAT,
96 (MSC01_PCI_INTCFG_MA_BIT |
97 MSC01_PCI_INTCFG_TA_BIT));
98
99 return -1;
100 }
101
102 return 0;
103}
104
105
106/*
107 * We can't address 8 and 16 bit words directly. Instead we have to
108 * read/write a 32bit word and mask/modify the data we actually want.
109 */
110static int msc_pcibios_read(struct pci_bus *bus, unsigned int devfn,
111 int where, int size, u32 * val)
112{
113 u32 data = 0;
114
115 if ((size == 2) && (where & 1))
116 return PCIBIOS_BAD_REGISTER_NUMBER;
117 else if ((size == 4) && (where & 3))
118 return PCIBIOS_BAD_REGISTER_NUMBER;
119
120 if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
121 &data))
122 return -1;
123
124 if (size == 1)
125 *val = (data >> ((where & 3) << 3)) & 0xff;
126 else if (size == 2)
127 *val = (data >> ((where & 3) << 3)) & 0xffff;
128 else
129 *val = data;
130
131 return PCIBIOS_SUCCESSFUL;
132}
133
134static int msc_pcibios_write(struct pci_bus *bus, unsigned int devfn,
135 int where, int size, u32 val)
136{
137 u32 data = 0;
138
139 if ((size == 2) && (where & 1))
140 return PCIBIOS_BAD_REGISTER_NUMBER;
141 else if ((size == 4) && (where & 3))
142 return PCIBIOS_BAD_REGISTER_NUMBER;
143
144 if (size == 4)
145 data = val;
146 else {
147 if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
148 where, &data))
149 return -1;
150
151 if (size == 1)
152 data = (data & ~(0xff << ((where & 3) << 3))) |
153 (val << ((where & 3) << 3));
154 else if (size == 2)
155 data = (data & ~(0xffff << ((where & 3) << 3))) |
156 (val << ((where & 3) << 3));
157 }
158
159 if (msc_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
160 &data))
161 return -1;
162
163 return PCIBIOS_SUCCESSFUL;
164}
165
166struct pci_ops msc_pci_ops = {
167 .read = msc_pcibios_read,
168 .write = msc_pcibios_write
169};
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
new file mode 100644
index 00000000000..a7169928b35
--- /dev/null
+++ b/arch/mips/pci/ops-nile4.c
@@ -0,0 +1,147 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/pci.h>
4#include <asm/bootinfo.h>
5
6#include <asm/lasat/lasat.h>
7#include <asm/gt64120.h>
8#include <asm/nile4.h>
9
10#define PCI_ACCESS_READ 0
11#define PCI_ACCESS_WRITE 1
12
13#define LO(reg) (reg / 4)
14#define HI(reg) (reg / 4 + 1)
15
16volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
17
18static spinlock_t nile4_pci_lock;
19
20static int nile4_pcibios_config_access(unsigned char access_type,
21 struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
22{
23 unsigned char busnum = bus->number;
24 u32 adr, mask, err;
25
26 if ((busnum == 0) && (PCI_SLOT(devfn) > 8))
27 /* The addressing scheme chosen leaves room for just
28 * 8 devices on the first busnum (besides the PCI
29 * controller itself) */
30 return PCIBIOS_DEVICE_NOT_FOUND;
31
32 if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) {
33 /* Access controller registers directly */
34 if (access_type == PCI_ACCESS_WRITE) {
35 vrc_pciregs[(0x200 + where) >> 2] = *val;
36 } else {
37 *val = vrc_pciregs[(0x200 + where) >> 2];
38 }
39 return PCIBIOS_SUCCESSFUL;
40 }
41
42 /* Temporarily map PCI Window 1 to config space */
43 mask = vrc_pciregs[LO(NILE4_PCIINIT1)];
44 vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0);
45
46 /* Clear PCI Error register. This also clears the Error Type
47 * bits in the Control register */
48 vrc_pciregs[LO(NILE4_PCIERR)] = 0;
49 vrc_pciregs[HI(NILE4_PCIERR)] = 0;
50
51 /* Setup address */
52 if (busnum == 0)
53 adr =
54 KSEG1ADDR(PCI_WINDOW1) +
55 ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8)
56 | (where & ~3));
57 else
58 adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) |
59 (where & ~3);
60
61 if (access_type == PCI_ACCESS_WRITE)
62 *(u32 *) adr = *val;
63 else
64 *val = *(u32 *) adr;
65
66 /* Check for master or target abort */
67 err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7;
68
69 /* Restore PCI Window 1 */
70 vrc_pciregs[LO(NILE4_PCIINIT1)] = mask;
71
72 if (err)
73 return PCIBIOS_DEVICE_NOT_FOUND;
74
75 return PCIBIOS_SUCCESSFUL;
76}
77
78static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
79 int where, int size, u32 * val)
80{
81 unsigned long flags;
82 u32 data = 0;
83 int err;
84
85 if ((size == 2) && (where & 1))
86 return PCIBIOS_BAD_REGISTER_NUMBER;
87 else if ((size == 4) && (where & 3))
88 return PCIBIOS_BAD_REGISTER_NUMBER;
89
90 spin_lock_irqsave(&nile4_pci_lock, flags);
91 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
92 &data);
93 spin_unlock_irqrestore(&nile4_pci_lock, flags);
94
95 if (err)
96 return err;
97
98 if (size == 1)
99 *val = (data >> ((where & 3) << 3)) & 0xff;
100 else if (size == 2)
101 *val = (data >> ((where & 3) << 3)) & 0xffff;
102 else
103 *val = data;
104
105 return PCIBIOS_SUCCESSFUL;
106}
107
108static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
109 int where, int size, u32 val)
110{
111 unsigned long flags;
112 u32 data = 0;
113 int err;
114
115 if ((size == 2) && (where & 1))
116 return PCIBIOS_BAD_REGISTER_NUMBER;
117 else if ((size == 4) && (where & 3))
118 return PCIBIOS_BAD_REGISTER_NUMBER;
119
120 spin_lock_irqsave(&nile4_pci_lock, flags);
121 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
122 &data);
123 spin_unlock_irqrestore(&nile4_pci_lock, flags);
124
125 if (err)
126 return err;
127
128 if (size == 1)
129 data = (data & ~(0xff << ((where & 3) << 3))) |
130 (val << ((where & 3) << 3));
131 else if (size == 2)
132 data = (data & ~(0xffff << ((where & 3) << 3))) |
133 (val << ((where & 3) << 3));
134 else
135 data = val;
136
137 if (nile4_pcibios_config_access
138 (PCI_ACCESS_WRITE, bus, devfn, where, &data))
139 return -1;
140
141 return PCIBIOS_SUCCESSFUL;
142}
143
144struct pci_ops nile4_pci_ops = {
145 .read = nile4_pcibios_read,
146 .write = nile4_pcibios_write,
147};
diff --git a/arch/mips/pci/ops-sni.c b/arch/mips/pci/ops-sni.c
new file mode 100644
index 00000000000..62bdd19c7f8
--- /dev/null
+++ b/arch/mips/pci/ops-sni.c
@@ -0,0 +1,89 @@
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 * SNI specific PCI support for RM200/RM300.
7 *
8 * Copyright (C) 1997 - 2000, 2003 Ralf Baechle <ralf@linux-mips.org>
9 */
10#include <linux/kernel.h>
11#include <linux/pci.h>
12#include <linux/types.h>
13#include <asm/sni.h>
14
15/*
16 * It seems that on the RM200 only lower 3 bits of the 5 bit PCI device
17 * address are decoded. We therefore manually have to reject attempts at
18 * reading outside this range. Being on the paranoid side we only do this
19 * test for bus 0 and hope forwarding and decoding work properly for any
20 * subordinated busses.
21 *
22 * ASIC PCI only supports type 1 config cycles.
23 */
24static int set_config_address(unsigned int busno, unsigned int devfn, int reg)
25{
26 if ((devfn > 255) || (reg > 255))
27 return PCIBIOS_BAD_REGISTER_NUMBER;
28
29 if (busno == 0 && devfn >= PCI_DEVFN(8, 0))
30 return PCIBIOS_DEVICE_NOT_FOUND;
31
32 *(volatile u32 *)PCIMT_CONFIG_ADDRESS =
33 ((busno & 0xff) << 16) |
34 ((devfn & 0xff) << 8) |
35 (reg & 0xfc);
36
37 return PCIBIOS_SUCCESSFUL;
38}
39
40static int pcimt_read(struct pci_bus *bus, unsigned int devfn, int reg,
41 int size, u32 * val)
42{
43 int res;
44
45 if ((res = set_config_address(bus->number, devfn, reg)))
46 return res;
47
48 switch (size) {
49 case 1:
50 *val = *(volatile u8 *) (PCIMT_CONFIG_DATA + (reg & 3));
51 break;
52 case 2:
53 *val = *(volatile u16 *) (PCIMT_CONFIG_DATA + (reg & 2));
54 break;
55 case 4:
56 *val = *(volatile u32 *) PCIMT_CONFIG_DATA;
57 break;
58 }
59
60 return 0;
61}
62
63static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg,
64 int size, u32 val)
65{
66 int res;
67
68 if ((res = set_config_address(bus->number, devfn, reg)))
69 return res;
70
71 switch (size) {
72 case 1:
73 *(volatile u8 *) (PCIMT_CONFIG_DATA + (reg & 3)) = val;
74 break;
75 case 2:
76 *(volatile u16 *) (PCIMT_CONFIG_DATA + (reg & 2)) = val;
77 break;
78 case 4:
79 *(volatile u32 *) PCIMT_CONFIG_DATA = val;
80 break;
81 }
82
83 return 0;
84}
85
86struct pci_ops sni_pci_ops = {
87 .read = pcimt_read,
88 .write = pcimt_write,
89};
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
new file mode 100644
index 00000000000..46c636c27e0
--- /dev/null
+++ b/arch/mips/pci/ops-titan-ht.c
@@ -0,0 +1,125 @@
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/slab.h>
30#include <linux/delay.h>
31#include <asm/io.h>
32
33#include <asm/titan_dep.h>
34
35static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
36 int offset, u32 * val)
37{
38 volatile uint32_t address;
39 int busno;
40
41 busno = bus->number;
42
43 address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
44 if (busno != 0)
45 address |= 1;
46
47 /*
48 * RM9000 HT Errata: Issue back to back HT config
49 * transcations. Issue a BIU sync before and
50 * after the HT cycle
51 */
52
53 *(volatile int32_t *) 0xfb0000f0 |= 0x2;
54
55 udelay(30);
56
57 *(volatile int32_t *) 0xfb0006f8 = address;
58 *(val) = *(volatile int32_t *) 0xfb0006fc;
59
60 udelay(30);
61
62 * (volatile int32_t *) 0xfb0000f0 |= 0x2;
63
64 return PCIBIOS_SUCCESSFUL;
65}
66
67static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn,
68 int offset, int size, u32 * val)
69{
70 uint32_t dword;
71
72 titan_ht_config_read_dword(bus, devfn, offset, &dword);
73
74 dword >>= ((offset & 3) << 3);
75 dword &= (0xffffffffU >> ((4 - size) << 8));
76
77 return PCIBIOS_SUCCESSFUL;
78}
79
80static inline int titan_ht_config_write_dword(struct pci_bus *bus,
81 unsigned int devfn, int offset, u32 val)
82{
83 volatile uint32_t address;
84 int busno;
85
86 busno = bus->number;
87
88 address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
89 if (busno != 0)
90 address |= 1;
91
92 *(volatile int32_t *) 0xfb0000f0 |= 0x2;
93
94 udelay(30);
95
96 *(volatile int32_t *) 0xfb0006f8 = address;
97 *(volatile int32_t *) 0xfb0006fc = val;
98
99 udelay(30);
100
101 *(volatile int32_t *) 0xfb0000f0 |= 0x2;
102
103 return PCIBIOS_SUCCESSFUL;
104}
105
106static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn,
107 int offset, int size, u32 val)
108{
109 uint32_t val1, val2, mask;
110
111 titan_ht_config_read_dword(bus, devfn, offset, &val2);
112
113 val1 = val << ((offset & 3) << 3);
114 mask = ~(0xffffffffU >> ((4 - size) << 8));
115 val2 &= ~(mask << ((offset & 3) << 8));
116
117 titan_ht_config_write_dword(bus, devfn, offset, val1 | val2);
118
119 return PCIBIOS_SUCCESSFUL;
120}
121
122struct pci_ops titan_ht_pci_ops = {
123 .read = titan_ht_config_read,
124 .write = titan_ht_config_write,
125};
diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c
new file mode 100644
index 00000000000..233ec6f2054
--- /dev/null
+++ b/arch/mips/pci/ops-titan.c
@@ -0,0 +1,100 @@
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/titan_dep.h>
30
31static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
32 int size, u32 * val)
33{
34 uint32_t address, tmp;
35 int dev, busno, func;
36
37 busno = bus->number;
38 dev = PCI_SLOT(devfn);
39 func = PCI_FUNC(devfn);
40
41 address = (busno << 16) | (dev << 11) | (func << 8) |
42 (reg & 0xfc) | 0x80000000;
43
44
45 /* start the configuration cycle */
46 TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
47 tmp = TITAN_READ(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
48
49 switch (size) {
50 case 1:
51 tmp &= 0xff;
52 case 2:
53 tmp &= 0xffff;
54 }
55 *val = tmp;
56
57 return PCIBIOS_SUCCESSFUL;
58}
59
60static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
61 int size, u32 val)
62{
63 uint32_t address;
64 int dev, busno, func;
65
66 busno = bus->number;
67 dev = PCI_SLOT(devfn);
68 func = PCI_FUNC(devfn);
69
70 address = (busno << 16) | (dev << 11) | (func << 8) |
71 (reg & 0xfc) | 0x80000000;
72
73 /* start the configuration cycle */
74 TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
75
76 /* write the data */
77 switch (size) {
78 case 1:
79 TITAN_WRITE_8(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3), val);
80 break;
81
82 case 2:
83 TITAN_WRITE_16(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2), val);
84 break;
85
86 case 4:
87 TITAN_WRITE(TITAN_PCI_0_CONFIG_DATA, val);
88 break;
89 }
90
91 return PCIBIOS_SUCCESSFUL;
92}
93
94/*
95 * Titan PCI structure
96 */
97struct pci_ops titan_pci_ops = {
98 titan_read_config,
99 titan_write_config,
100};
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c
new file mode 100644
index 00000000000..0e0daadc303
--- /dev/null
+++ b/arch/mips/pci/ops-tx3927.c
@@ -0,0 +1,391 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * Copyright (C) 2000-2001 Toshiba Corporation
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
10 *
11 * Define the pci_ops for JMR3927.
12 *
13 * Much of the code is derived from the original DDB5074 port by
14 * Geert Uytterhoeven <geert@sonycom.com>
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 *
21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
24 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * You should have received a copy of the GNU General Public License along
33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36#include <linux/types.h>
37#include <linux/pci.h>
38#include <linux/kernel.h>
39#include <linux/init.h>
40
41#include <asm/addrspace.h>
42#include <asm/jmr3927/jmr3927.h>
43#include <asm/debug.h>
44
45static inline int mkaddr(unsigned char bus, unsigned char dev_fn,
46 unsigned char where)
47{
48 if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
49 return PCIBIOS_DEVICE_NOT_FOUND;
50
51 tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) |
52 ((dev_fn & 0xff) << 0x08) |
53 (where & 0xfc);
54
55 /* clear M_ABORT and Disable M_ABORT Int. */
56 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
57 tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
58
59 return PCIBIOS_SUCCESSFUL;
60}
61
62static inline int check_abort(void)
63{
64 if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
65 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
66 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
67 return PCIBIOS_DEVICE_NOT_FOUND;
68
69 return PCIBIOS_SUCCESSFUL;
70}
71
72static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
73 int where, int size, u32 * val)
74{
75 int ret, busno;
76
77 /* check if the bus is top-level */
78 if (bus->parent != NULL)
79 busno = bus->number;
80
81 ret = mkaddr(busno, devfn, where);
82 if (ret)
83 return ret;
84
85 switch (size) {
86 case 1:
87 *val = *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3));
88 break;
89
90 case 2:
91 *val = le16_to_cpu(*(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)));
92 break;
93
94 case 4:
95 *val = le32_to_cpu(tx3927_pcicptr->icd);
96 break;
97 }
98
99 return check_abort();
100}
101
102static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
103 int where, int size, u32 val)
104{
105 int ret, busno;
106
107 /* check if the bus is top-level */
108 if (bus->parent != NULL)
109 bus = bus->number;
110 else
111 bus = 0;
112
113 ret = mkaddr(busno, devfn, where);
114 if (ret)
115 return ret;
116
117 switch (size) {
118 case 1:
119 *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)) = val;
120 break;
121
122 case 2:
123 *(volatile u16 *) (unsigned longulong) & tx3927_pcicptr->icd | (where & 2)) =
124 cpu_to_le16(val);
125 break;
126
127 case 4:
128 tx3927_pcicptr->icd = cpu_to_le32(val);
129 }
130
131 if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
132 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
133 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
134 return PCIBIOS_DEVICE_NOT_FOUND;
135
136 return check_abort();
137}
138
139struct pci_ops jmr3927_pci_ops = {
140 jmr3927_pcibios_read_config,
141 jmr3927_pcibios_write_config,
142};
143
144
145#ifndef JMR3927_INIT_INDIRECT_PCI
146
147inline unsigned long tc_readl(volatile __u32 * addr)
148{
149 return readl(addr);
150}
151
152inline void tc_writel(unsigned long data, volatile __u32 * addr)
153{
154 writel(data, addr);
155}
156#else
157
158unsigned long tc_readl(volatile __u32 * addr)
159{
160 unsigned long val;
161
162 addr = PHYSADDR(addr);
163 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
164 (unsigned long) addr;
165 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
166 (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) |
167 PCI_IPCIBE_IBE_LONG;
168 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
169 val =
170 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
171 ipcidata);
172 /* clear by setting */
173 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
174 return val;
175}
176
177void tc_writel(unsigned long data, volatile __u32 * addr)
178{
179 addr = PHYSADDR(addr);
180 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata =
181 cpu_to_le32(data);
182 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
183 (unsigned long) addr;
184 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
185 (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) |
186 PCI_IPCIBE_IBE_LONG;
187 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
188 /* clear by setting */
189 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
190}
191
192unsigned char tx_ioinb(unsigned char *addr)
193{
194 unsigned long val;
195 __u32 ioaddr;
196 int offset;
197 int byte;
198
199 ioaddr = (unsigned long) addr;
200 offset = ioaddr & 0x3;
201 if (offset == 0)
202 byte = 0x7;
203 else if (offset == 1)
204 byte = 0xb;
205 else if (offset == 2)
206 byte = 0xd;
207 else if (offset == 3)
208 byte = 0xe;
209 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
210 (unsigned long) ioaddr;
211 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
212 (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
213 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
214 val =
215 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
216 ipcidata);
217 val = val & 0xff;
218 /* clear by setting */
219 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
220 return val;
221}
222
223void tx_iooutb(unsigned long data, unsigned char *addr)
224{
225 __u32 ioaddr;
226 int offset;
227 int byte;
228
229 data = data | (data << 8) | (data << 16) | (data << 24);
230 ioaddr = (unsigned long) addr;
231 offset = ioaddr & 0x3;
232 if (offset == 0)
233 byte = 0x7;
234 else if (offset == 1)
235 byte = 0xb;
236 else if (offset == 2)
237 byte = 0xd;
238 else if (offset == 3)
239 byte = 0xe;
240 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data;
241 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
242 (unsigned long) ioaddr;
243 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
244 (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte;
245 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
246 /* clear by setting */
247 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
248}
249
250unsigned short tx_ioinw(unsigned short *addr)
251{
252 unsigned long val;
253 __u32 ioaddr;
254 int offset;
255 int byte;
256
257 ioaddr = (unsigned long) addr;
258 offset = ioaddr & 0x3;
259 if (offset == 0)
260 byte = 0x3;
261 else if (offset == 2)
262 byte = 0xc;
263 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
264 (unsigned long) ioaddr;
265 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
266 (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte;
267 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
268 val =
269 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
270 ipcidata);
271 val = val & 0xffff;
272 /* clear by setting */
273 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
274 return val;
275
276}
277
278void tx_iooutw(unsigned long data, unsigned short *addr)
279{
280 __u32 ioaddr;
281 int offset;
282 int byte;
283
284 data = data | (data << 16);
285 ioaddr = (unsigned long) addr;
286 offset = ioaddr & 0x3;
287 if (offset == 0)
288 byte = 0x3;
289 else if (offset == 2)
290 byte = 0xc;
291 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data;
292 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
293 (unsigned long) ioaddr;
294 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
295 (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte;
296 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
297 /* clear by setting */
298 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
299}
300
301unsigned long tx_ioinl(unsigned int *addr)
302{
303 unsigned long val;
304 __u32 ioaddr;
305
306 ioaddr = (unsigned long) addr;
307 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
308 (unsigned long) ioaddr;
309 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
310 (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) |
311 PCI_IPCIBE_IBE_LONG;
312 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
313 val =
314 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr->
315 ipcidata);
316 /* clear by setting */
317 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
318 return val;
319}
320
321void tx_iooutl(unsigned long data, unsigned int *addr)
322{
323 __u32 ioaddr;
324
325 ioaddr = (unsigned long) addr;
326 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata =
327 cpu_to_le32(data);
328 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr =
329 (unsigned long) ioaddr;
330 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe =
331 (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) |
332 PCI_IPCIBE_IBE_LONG;
333 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC));
334 /* clear by setting */
335 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC;
336}
337
338void tx_insbyte(unsigned char *addr, void *buffer, unsigned int count)
339{
340 unsigned char *ptr = (unsigned char *) buffer;
341
342 while (count--) {
343 *ptr++ = tx_ioinb(addr);
344 }
345}
346
347void tx_insword(unsigned short *addr, void *buffer, unsigned int count)
348{
349 unsigned short *ptr = (unsigned short *) buffer;
350
351 while (count--) {
352 *ptr++ = tx_ioinw(addr);
353 }
354}
355
356void tx_inslong(unsigned int *addr, void *buffer, unsigned int count)
357{
358 unsigned long *ptr = (unsigned long *) buffer;
359
360 while (count--) {
361 *ptr++ = tx_ioinl(addr);
362 }
363}
364
365void tx_outsbyte(unsigned char *addr, void *buffer, unsigned int count)
366{
367 unsigned char *ptr = (unsigned char *) buffer;
368
369 while (count--) {
370 tx_iooutb(*ptr++, addr);
371 }
372}
373
374void tx_outsword(unsigned short *addr, void *buffer, unsigned int count)
375{
376 unsigned short *ptr = (unsigned short *) buffer;
377
378 while (count--) {
379 tx_iooutw(*ptr++, addr);
380 }
381}
382
383void tx_outslong(unsigned int *addr, void *buffer, unsigned int count)
384{
385 unsigned long *ptr = (unsigned long *) buffer;
386
387 while (count--) {
388 tx_iooutl(*ptr++, addr);
389 }
390}
391#endif
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
new file mode 100644
index 00000000000..2a9d7227fe8
--- /dev/null
+++ b/arch/mips/pci/ops-tx4927.c
@@ -0,0 +1,209 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * Copyright (C) 2000-2001 Toshiba Corporation
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
10 *
11 * Define the pci_ops for the Toshiba rbtx4927
12 *
13 * Much of the code is derived from the original DDB5074 port by
14 * Geert Uytterhoeven <geert@sonycom.com>
15 *
16 * Copyright 2004 MontaVista Software Inc.
17 * Author: Manish Lachwani (mlachwani@mvista.com)
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the
21 * Free Software Foundation; either version 2 of the License, or (at your
22 * option) any later version.
23 *
24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
27 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 * You should have received a copy of the GNU General Public License along
36 * with this program; if not, write to the Free Software Foundation, Inc.,
37 * 675 Mass Ave, Cambridge, MA 02139, USA.
38 */
39#include <linux/types.h>
40#include <linux/pci.h>
41#include <linux/kernel.h>
42#include <linux/init.h>
43
44#include <asm/addrspace.h>
45#include <asm/byteorder.h>
46#include <asm/tx4927/tx4927_pci.h>
47
48/* initialize in setup */
49struct resource pci_io_resource = {
50 .name = "TX4927 PCI IO SPACE",
51 .start = 0x1000,
52 .end = (0x1000 + (TX4927_PCIIO_SIZE)) - 1,
53 .flags = IORESOURCE_IO
54};
55
56/* initialize in setup */
57struct resource pci_mem_resource = {
58 .name = "TX4927 PCI MEM SPACE",
59 .start = TX4927_PCIMEM,
60 .end = TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1,
61 .flags = IORESOURCE_MEM
62};
63
64static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
65{
66 if (bus > 0) {
67 /* Type 1 configuration */
68 tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
69 ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
70 } else {
71 if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0))
72 return -1;
73
74 /* Type 0 configuration */
75 tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
76 ((dev_fn & 0xff) << 0x08) | (where & 0xfc);
77 }
78 /* clear M_ABORT and Disable M_ABORT Int. */
79 tx4927_pcicptr->pcistatus =
80 (tx4927_pcicptr->pcistatus & 0x0000ffff) |
81 (PCI_STATUS_REC_MASTER_ABORT << 16);
82 tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
83 return 0;
84}
85
86static int check_abort(int flags)
87{
88 int code = PCIBIOS_SUCCESSFUL;
89 if (tx4927_pcicptr->
90 pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
91 tx4927_pcicptr->pcistatus =
92 (tx4927_pcicptr->
93 pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
94 << 16);
95 tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
96 code = PCIBIOS_DEVICE_NOT_FOUND;
97 }
98 return code;
99}
100
101static int tx4927_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where,
102 int size, u32 * val)
103{
104 int flags, retval, dev, busno, func;
105
106 busno = bus->number;
107 dev = PCI_SLOT(devfn);
108 func = PCI_FUNC(devfn);
109
110 /* check if the bus is top-level */
111 if (bus->parent != NULL) {
112 busno = bus->number;
113 } else {
114 busno = 0;
115 }
116
117 if (mkaddr(busno, devfn, where, &flags))
118 return -1;
119
120 switch (size) {
121 case 1:
122 *val = *(volatile u8 *) ((ulong) & tx4927_pcicptr->
123 g2pcfgdata |
124#ifdef __LITTLE_ENDIAN
125 (where & 3));
126#else
127 ((where & 0x3) ^ 0x3));
128#endif
129 break;
130 case 2:
131 *val = *(volatile u16 *) ((ulong) & tx4927_pcicptr->
132 g2pcfgdata |
133#ifdef __LITTLE_ENDIAN
134 (where & 3));
135#else
136 ((where & 0x3) ^ 0x2));
137#endif
138 break;
139 case 4:
140 *val = tx4927_pcicptr->g2pcfgdata;
141 break;
142 }
143
144 retval = check_abort(flags);
145 if (retval == PCIBIOS_DEVICE_NOT_FOUND)
146 *val = 0xffffffff;
147
148 return retval;
149}
150
151static int tx4927_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
152 int size, u32 val)
153{
154 int flags, dev, busno, func;
155 busno = bus->number;
156 dev = PCI_SLOT(devfn);
157 func = PCI_FUNC(devfn);
158
159 /* check if the bus is top-level */
160 if (bus->parent != NULL) {
161 busno = bus->number;
162 } else {
163 busno = 0;
164 }
165
166 if (mkaddr(busno, devfn, where, &flags))
167 return -1;
168
169 switch (size) {
170 case 1:
171 *(volatile u8 *) ((ulong) & tx4927_pcicptr->
172 g2pcfgdata |
173#ifdef __LITTLE_ENDIAN
174 (where & 3)) = val;
175#else
176 ((where & 0x3) ^ 0x3)) = val;
177#endif
178 break;
179
180 case 2:
181 *(volatile u16 *) ((ulong) & tx4927_pcicptr->
182 g2pcfgdata |
183#ifdef __LITTLE_ENDIAN
184 (where & 3)) = val;
185#else
186 ((where & 0x3) ^ 0x2)) = val;
187#endif
188 break;
189 case 4:
190 tx4927_pcicptr->g2pcfgdata = val;
191 break;
192 }
193
194 return check_abort(flags);
195}
196
197struct pci_ops tx4927_pci_ops = {
198 tx4927_pcibios_read_config,
199 tx4927_pcibios_write_config
200};
201
202/*
203 * h/w only supports devices 0x00 to 0x14
204 */
205struct pci_controller tx4927_controller = {
206 .pci_ops = &tx4927_pci_ops,
207 .io_resource = &pci_io_resource,
208 .mem_resource = &pci_mem_resource,
209};
diff --git a/arch/mips/pci/ops-vr41xx.c b/arch/mips/pci/ops-vr41xx.c
new file mode 100644
index 00000000000..44654605e46
--- /dev/null
+++ b/arch/mips/pci/ops-vr41xx.c
@@ -0,0 +1,126 @@
1/*
2 * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series.
3 *
4 * Copyright (C) 2001-2003 MontaVista Software Inc.
5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6 * Copyright (C) 2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22/*
23 * Changes:
24 * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
25 * - New creation, NEC VR4122 and VR4131 are supported.
26 */
27#include <linux/pci.h>
28#include <linux/types.h>
29
30#include <asm/io.h>
31
32#define PCICONFDREG KSEG1ADDR(0x0f000c14)
33#define PCICONFAREG KSEG1ADDR(0x0f000c18)
34
35static inline int set_pci_configuration_address(unsigned char number,
36 unsigned int devfn, int where)
37{
38 if (number == 0) {
39 /*
40 * Type 0 configuration
41 */
42 if (PCI_SLOT(devfn) < 11 || where > 0xff)
43 return -EINVAL;
44
45 writel((1U << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) |
46 (where & 0xfc), PCICONFAREG);
47 } else {
48 /*
49 * Type 1 configuration
50 */
51 if (where > 0xff)
52 return -EINVAL;
53
54 writel(((uint32_t)number << 16) | ((devfn & 0xff) << 8) |
55 (where & 0xfc) | 1U, PCICONFAREG);
56 }
57
58 return 0;
59}
60
61static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
62 int size, uint32_t *val)
63{
64 uint32_t data;
65
66 *val = 0xffffffffU;
67 if (set_pci_configuration_address(bus->number, devfn, where) < 0)
68 return PCIBIOS_DEVICE_NOT_FOUND;
69
70 data = readl(PCICONFDREG);
71
72 switch (size) {
73 case 1:
74 *val = (data >> ((where & 3) << 3)) & 0xffU;
75 break;
76 case 2:
77 *val = (data >> ((where & 2) << 3)) & 0xffffU;
78 break;
79 case 4:
80 *val = data;
81 break;
82 default:
83 return PCIBIOS_FUNC_NOT_SUPPORTED;
84 }
85
86 return PCIBIOS_SUCCESSFUL;
87}
88
89static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
90 int size, uint32_t val)
91{
92 uint32_t data;
93 int shift;
94
95 if (set_pci_configuration_address(bus->number, devfn, where) < 0)
96 return PCIBIOS_DEVICE_NOT_FOUND;
97
98 data = readl(PCICONFDREG);
99
100 switch (size) {
101 case 1:
102 shift = (where & 3) << 3;
103 data &= ~(0xffU << shift);
104 data |= ((val & 0xffU) << shift);
105 break;
106 case 2:
107 shift = (where & 2) << 3;
108 data &= ~(0xffffU << shift);
109 data |= ((val & 0xffffU) << shift);
110 break;
111 case 4:
112 data = val;
113 break;
114 default:
115 return PCIBIOS_FUNC_NOT_SUPPORTED;
116 }
117
118 writel(data, PCICONFDREG);
119
120 return PCIBIOS_SUCCESSFUL;
121}
122
123struct pci_ops vr41xx_pci_ops = {
124 .read = pci_config_read,
125 .write = pci_config_write,
126};
diff --git a/arch/mips/pci/pci-ddb5074.c b/arch/mips/pci/pci-ddb5074.c
new file mode 100644
index 00000000000..73f9ceeb2f5
--- /dev/null
+++ b/arch/mips/pci/pci-ddb5074.c
@@ -0,0 +1,79 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/types.h>
4#include <linux/pci.h>
5
6#include <asm/debug.h>
7
8#include <asm/ddb5xxx/ddb5xxx.h>
9
10static struct resource extpci_io_resource = {
11 "pci IO space",
12 0x1000, /* leave some room for ISA bus */
13 DDB_PCI_IO_SIZE - 1,
14 IORESOURCE_IO
15};
16
17static struct resource extpci_mem_resource = {
18 "pci memory space",
19 DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */
20 DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1,
21 IORESOURCE_MEM
22};
23
24extern struct pci_ops ddb5476_ext_pci_ops;
25
26struct pci_controller ddb5476_controller = {
27 .pci_ops = &ddb5476_ext_pci_ops,
28 .io_resource = &extpci_io_resource,
29 .mem_resource = &extpci_mem_resource,
30};
31
32#define PCI_EXT_INTA 8
33#define PCI_EXT_INTB 9
34#define PCI_EXT_INTC 10
35#define PCI_EXT_INTD 11
36#define PCI_EXT_INTE 12
37
38#define MAX_SLOT_NUM 14
39
40static unsigned char irq_map[MAX_SLOT_NUM] = {
41 [ 0] = nile4_to_irq(PCI_EXT_INTE),
42 [ 1] = nile4_to_irq(PCI_EXT_INTA),
43 [ 2] = nile4_to_irq(PCI_EXT_INTA),
44 [ 3] = nile4_to_irq(PCI_EXT_INTB),
45 [ 4] = nile4_to_irq(PCI_EXT_INTC),
46 [ 5] = nile4_to_irq(NILE4_INT_UART),
47 [10] = nile4_to_irq(PCI_EXT_INTE),
48 [13] = nile4_to_irq(PCI_EXT_INTE),
49};
50
51int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
52{
53 return irq_map[slot];
54}
55
56/* Do platform specific device initialization at pci_enable_device() time */
57int pcibios_plat_dev_init(struct pci_dev *dev)
58{
59 return 0;
60}
61
62void __init ddb_pci_reset_bus(void)
63{
64 u32 temp;
65
66 /*
67 * I am not sure about the "official" procedure, the following
68 * steps work as far as I know:
69 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
70 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
71 * The same is true for both PCI channels.
72 */
73 temp = ddb_in32(DDB_PCICTRL + 4);
74 temp |= 0x80000000;
75 ddb_out32(DDB_PCICTRL + 4, temp);
76 temp &= ~0xc0000000;
77 ddb_out32(DDB_PCICTRL + 4, temp);
78
79}
diff --git a/arch/mips/pci/pci-ddb5476.c b/arch/mips/pci/pci-ddb5476.c
new file mode 100644
index 00000000000..90dd4950980
--- /dev/null
+++ b/arch/mips/pci/pci-ddb5476.c
@@ -0,0 +1,93 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/types.h>
4#include <linux/pci.h>
5
6#include <asm/debug.h>
7
8#include <asm/ddb5xxx/ddb5xxx.h>
9
10static struct resource extpci_io_resource = {
11 "pci IO space",
12 0x1000, /* leave some room for ISA bus */
13 DDB_PCI_IO_SIZE - 1,
14 IORESOURCE_IO
15};
16
17static struct resource extpci_mem_resource = {
18 "pci memory space",
19 DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */
20 DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1,
21 IORESOURCE_MEM
22};
23
24extern struct pci_ops ddb5476_ext_pci_ops;
25
26struct pci_controller ddb5476_controller = {
27 .pci_ops = &ddb5476_ext_pci_ops,
28 .io_resource = &extpci_io_resource,
29 .mem_resource = &extpci_mem_resource
30};
31
32
33/*
34 * we fix up irqs based on the slot number.
35 * The first entry is at AD:11.
36 *
37 * This does not work for devices on sub-buses yet.
38 */
39
40/*
41 * temporary
42 */
43
44#define PCI_EXT_INTA 8
45#define PCI_EXT_INTB 9
46#define PCI_EXT_INTC 10
47#define PCI_EXT_INTD 11
48#define PCI_EXT_INTE 12
49
50/*
51 * based on ddb5477 manual page 11
52 */
53#define MAX_SLOT_NUM 21
54static unsigned char irq_map[MAX_SLOT_NUM] = {
55 [ 2] = 9, /* AD:13 USB */
56 [ 3] = 10, /* AD:14 PMU */
57 [ 5] = 0, /* AD:16 P2P bridge */
58 [ 6] = nile4_to_irq(PCI_EXT_INTB), /* AD:17 */
59 [ 7] = nile4_to_irq(PCI_EXT_INTC), /* AD:18 */
60 [ 8] = nile4_to_irq(PCI_EXT_INTD), /* AD:19 */
61 [ 9] = nile4_to_irq(PCI_EXT_INTA), /* AD:20 */
62 [13] = 14, /* AD:24 HD controller, M5229 */
63};
64
65int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
66{
67 return irq_map[slot];
68}
69
70/* Do platform specific device initialization at pci_enable_device() time */
71int pcibios_plat_dev_init(struct pci_dev *dev)
72{
73 return 0;
74}
75
76void __init ddb_pci_reset_bus(void)
77{
78 u32 temp;
79
80 /*
81 * I am not sure about the "official" procedure, the following
82 * steps work as far as I know:
83 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
84 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
85 * The same is true for both PCI channels.
86 */
87 temp = ddb_in32(DDB_PCICTRL + 4);
88 temp |= 0x80000000;
89 ddb_out32(DDB_PCICTRL + 4, temp);
90 temp &= ~0xc0000000;
91 ddb_out32(DDB_PCICTRL + 4, temp);
92
93}
diff --git a/arch/mips/pci/pci-ddb5477.c b/arch/mips/pci/pci-ddb5477.c
new file mode 100644
index 00000000000..4ddd53eaf65
--- /dev/null
+++ b/arch/mips/pci/pci-ddb5477.c
@@ -0,0 +1,207 @@
1/*
2 * PCI code for DDB5477.
3 *
4 * Copyright (C) 2001 MontaVista Software Inc.
5 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
6 *
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/pci.h>
18
19#include <asm/bootinfo.h>
20#include <asm/debug.h>
21
22#include <asm/ddb5xxx/ddb5xxx.h>
23
24static struct resource extpci_io_resource = {
25 "ext pci IO space",
26 DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000,
27 DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE - 1,
28 IORESOURCE_IO
29};
30
31static struct resource extpci_mem_resource = {
32 "ext pci memory space",
33 DDB_PCI0_MEM_BASE + 0x100000,
34 DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE - 1,
35 IORESOURCE_MEM
36};
37
38static struct resource iopci_io_resource = {
39 "io pci IO space",
40 DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE,
41 DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE - 1,
42 IORESOURCE_IO
43};
44
45static struct resource iopci_mem_resource = {
46 "ext pci memory space",
47 DDB_PCI1_MEM_BASE,
48 DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE - 1,
49 IORESOURCE_MEM
50};
51
52extern struct pci_ops ddb5477_ext_pci_ops;
53extern struct pci_ops ddb5477_io_pci_ops;
54
55struct pci_controller ddb5477_ext_controller = {
56 .pci_ops = &ddb5477_ext_pci_ops,
57 .io_resource = &extpci_io_resource,
58 .mem_resource = &extpci_mem_resource
59};
60
61struct pci_controller ddb5477_io_controller = {
62 .pci_ops = &ddb5477_io_pci_ops,
63 .io_resource = &iopci_io_resource,
64 .mem_resource = &iopci_mem_resource
65};
66
67
68
69/*
70 * we fix up irqs based on the slot number.
71 * The first entry is at AD:11.
72 * Fortunately this works because, although we have two pci buses,
73 * they all have different slot numbers (except for rockhopper slot 20
74 * which is handled below).
75 *
76 */
77
78/*
79 * irq mapping : device -> pci int # -> vrc4377 irq# ,
80 * ddb5477 board manual page 4 and vrc5477 manual page 46
81 */
82
83/*
84 * based on ddb5477 manual page 11
85 */
86#define MAX_SLOT_NUM 21
87static unsigned char irq_map[MAX_SLOT_NUM] = {
88 /* SLOT: 0, AD:11 */ 0xff,
89 /* SLOT: 1, AD:12 */ 0xff,
90 /* SLOT: 2, AD:13 */ 0xff,
91 /* SLOT: 3, AD:14 */ 0xff,
92 /* SLOT: 4, AD:15 */ VRC5477_IRQ_INTA, /* onboard tulip */
93 /* SLOT: 5, AD:16 */ VRC5477_IRQ_INTB, /* slot 1 */
94 /* SLOT: 6, AD:17 */ VRC5477_IRQ_INTC, /* slot 2 */
95 /* SLOT: 7, AD:18 */ VRC5477_IRQ_INTD, /* slot 3 */
96 /* SLOT: 8, AD:19 */ VRC5477_IRQ_INTE, /* slot 4 */
97 /* SLOT: 9, AD:20 */ 0xff,
98 /* SLOT: 10, AD:21 */ 0xff,
99 /* SLOT: 11, AD:22 */ 0xff,
100 /* SLOT: 12, AD:23 */ 0xff,
101 /* SLOT: 13, AD:24 */ 0xff,
102 /* SLOT: 14, AD:25 */ 0xff,
103 /* SLOT: 15, AD:26 */ 0xff,
104 /* SLOT: 16, AD:27 */ 0xff,
105 /* SLOT: 17, AD:28 */ 0xff,
106 /* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
107 /* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
108 /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
109};
110static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = {
111 /* SLOT: 0, AD:11 */ 0xff,
112 /* SLOT: 1, AD:12 */ VRC5477_IRQ_INTB, /* onboard AMD PCNET */
113 /* SLOT: 2, AD:13 */ 0xff,
114 /* SLOT: 3, AD:14 */ 0xff,
115 /* SLOT: 4, AD:15 */ 14, /* M5229 ide ISA irq */
116 /* SLOT: 5, AD:16 */ VRC5477_IRQ_INTD, /* slot 3 */
117 /* SLOT: 6, AD:17 */ VRC5477_IRQ_INTA, /* slot 4 */
118 /* SLOT: 7, AD:18 */ VRC5477_IRQ_INTD, /* slot 5 */
119 /* SLOT: 8, AD:19 */ 0, /* M5457 modem nop */
120 /* SLOT: 9, AD:20 */ VRC5477_IRQ_INTA, /* slot 2 */
121 /* SLOT: 10, AD:21 */ 0xff,
122 /* SLOT: 11, AD:22 */ 0xff,
123 /* SLOT: 12, AD:23 */ 0xff,
124 /* SLOT: 13, AD:24 */ 0xff,
125 /* SLOT: 14, AD:25 */ 0xff,
126 /* SLOT: 15, AD:26 */ 0xff,
127 /* SLOT: 16, AD:27 */ 0xff,
128 /* SLOT: 17, AD:28 */ 0, /* M7101 PMU nop */
129 /* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, /* vrc5477 ac97 */
130 /* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, /* vrc5477 usb peri */
131 /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, /* vrc5477 usb host */
132};
133
134int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
135{
136 int slot_num;
137 unsigned char *slot_irq_map;
138 unsigned char irq;
139
140 /*
141 * We ignore the swizzled slot and pin values. The original
142 * pci_fixup_irq() codes largely base irq number on the dev slot
143 * numbers because except for one case they are unique even
144 * though there are multiple pci buses.
145 */
146
147 if (mips_machtype == MACH_NEC_ROCKHOPPERII)
148 slot_irq_map = rockhopperII_irq_map;
149 else
150 slot_irq_map = irq_map;
151
152 slot_num = PCI_SLOT(dev->devfn);
153 irq = slot_irq_map[slot_num];
154
155 db_assert(slot_num < MAX_SLOT_NUM);
156
157 db_assert(irq != 0xff);
158
159 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
160
161 if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
162 /* hack to distinquish overlapping slot 20s, one
163 * on bus 0 (ALI USB on the M1535 on the backplane),
164 * and one on bus 2 (NEC USB controller on the CPU board)
165 * Make the M1535 USB - ISA IRQ number 9.
166 */
167 if (slot_num == 20 && dev->bus->number == 0) {
168 pci_write_config_byte(dev,
169 PCI_INTERRUPT_LINE,
170 9);
171 irq = 9;
172 }
173
174 }
175
176 return irq;
177}
178
179/* Do platform specific device initialization at pci_enable_device() time */
180int pcibios_plat_dev_init(struct pci_dev *dev)
181{
182 return 0;
183}
184
185void ddb_pci_reset_bus(void)
186{
187 u32 temp;
188
189 /*
190 * I am not sure about the "official" procedure, the following
191 * steps work as far as I know:
192 * We first set PCI cold reset bit (bit 31) in PCICTRL-H.
193 * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H.
194 * The same is true for both PCI channels.
195 */
196 temp = ddb_in32(DDB_PCICTL0_H);
197 temp |= 0x80000000;
198 ddb_out32(DDB_PCICTL0_H, temp);
199 temp &= ~0xc0000000;
200 ddb_out32(DDB_PCICTL0_H, temp);
201
202 temp = ddb_in32(DDB_PCICTL1_H);
203 temp |= 0x80000000;
204 ddb_out32(DDB_PCICTL1_H, temp);
205 temp &= ~0xc0000000;
206 ddb_out32(DDB_PCICTL1_H, temp);
207}
diff --git a/arch/mips/pci/pci-ev96100.c b/arch/mips/pci/pci-ev96100.c
new file mode 100644
index 00000000000..f9457ea00de
--- /dev/null
+++ b/arch/mips/pci/pci-ev96100.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright 2000 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ppopov@mvista.com or source@mvista.com
5 *
6 * Carsten Langgaard, carstenl@mips.com
7 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
8 *
9 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31#include <linux/types.h>
32#include <linux/pci.h>
33#include <linux/kernel.h>
34#include <linux/init.h>
35
36static struct resource pci_io_resource = {
37 .name = "io pci IO space",
38 .start = 0x10000000,
39 .end = 0x11ffffff,
40 .flags = IORESOURCE_IO
41};
42
43static struct resource pci_mem_resource = {
44 .name = "ext pci memory space",
45 .start = 0x12000000,
46 .end = 0x13ffffff,
47 .flags = IORESOURCE_MEM
48};
49
50extern struct pci_ops gt96100_pci_ops;
51
52struct pci_controller ev96100_controller = {
53 .pci_ops = &gt96100_pci_ops,
54 .io_resource = &pci_io_resource,
55 .mem_resource = &pci_mem_resource,
56};
57
58static void ev96100_pci_init(void)
59{
60 register_pci_controller(&ev96100_controller);
61}
62
63arch_initcall(ev96100_pci_init);
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
new file mode 100644
index 00000000000..068e0e508e1
--- /dev/null
+++ b/arch/mips/pci/pci-ip27.c
@@ -0,0 +1,489 @@
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) 2003 Christoph Hellwig (hch@lst.de)
7 * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org)
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
9 */
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/pci.h>
13#include <asm/sn/arch.h>
14#include <asm/pci/bridge.h>
15#include <asm/paccess.h>
16#include <asm/sn/intr.h>
17#include <asm/sn/sn0/hub.h>
18
19extern unsigned int allocate_irqno(void);
20
21/*
22 * Max #PCI busses we can handle; ie, max #PCI bridges.
23 */
24#define MAX_PCI_BUSSES 40
25
26/*
27 * Max #PCI devices (like scsi controllers) we handle on a bus.
28 */
29#define MAX_DEVICES_PER_PCIBUS 8
30
31/*
32 * XXX: No kmalloc available when we do our crosstalk scan,
33 * we should try to move it later in the boot process.
34 */
35static struct bridge_controller bridges[MAX_PCI_BUSSES];
36
37/*
38 * Translate from irq to software PCI bus number and PCI slot.
39 */
40struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
41int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
42
43/*
44 * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
45 * not really documented, so right now I can't write code which uses it.
46 * Therefore we use type 0 accesses for now even though they won't work
47 * correcly for PCI-to-PCI bridges.
48 *
49 * The function is complicated by the ultimate brokeness of the IOC3 chip
50 * which is used in SGI systems. The IOC3 can only handle 32-bit PCI
51 * accesses and does only decode parts of it's address space.
52 */
53
54static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
55 int where, int size, u32 * value)
56{
57 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
58 bridge_t *bridge = bc->base;
59 int slot = PCI_SLOT(devfn);
60 int fn = PCI_FUNC(devfn);
61 volatile void *addr;
62 u32 cf, shift, mask;
63 int res;
64
65 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
66 if (get_dbe(cf, (u32 *) addr))
67 return PCIBIOS_DEVICE_NOT_FOUND;
68
69 /*
70 * IOC3 is fucked fucked beyond believe ... Don't even give the
71 * generic PCI code a chance to look at it for real ...
72 */
73 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
74 goto oh_my_gawd;
75
76 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
77
78 if (size == 1)
79 res = get_dbe(*value, (u8 *) addr);
80 else if (size == 2)
81 res = get_dbe(*value, (u16 *) addr);
82 else
83 res = get_dbe(*value, (u32 *) addr);
84
85 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
86
87oh_my_gawd:
88
89 /*
90 * IOC3 is fucked fucked beyond believe ... Don't even give the
91 * generic PCI code a chance to look at the wrong register.
92 */
93 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
94 *value = 0;
95 return PCIBIOS_SUCCESSFUL;
96 }
97
98 /*
99 * IOC3 is fucked fucked beyond believe ... Don't try to access
100 * anything but 32-bit words ...
101 */
102 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
103
104 if (get_dbe(cf, (u32 *) addr))
105 return PCIBIOS_DEVICE_NOT_FOUND;
106
107 shift = ((where & 3) << 3);
108 mask = (0xffffffffU >> ((4 - size) << 3));
109 *value = (cf >> shift) & mask;
110
111 return PCIBIOS_SUCCESSFUL;
112}
113
114static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
115 int where, int size, u32 * value)
116{
117 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
118 bridge_t *bridge = bc->base;
119 int busno = bus->number;
120 int slot = PCI_SLOT(devfn);
121 int fn = PCI_FUNC(devfn);
122 volatile void *addr;
123 u32 cf, shift, mask;
124 int res;
125
126 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
127 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
128 if (get_dbe(cf, (u32 *) addr))
129 return PCIBIOS_DEVICE_NOT_FOUND;
130
131 /*
132 * IOC3 is fucked fucked beyond believe ... Don't even give the
133 * generic PCI code a chance to look at it for real ...
134 */
135 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
136 goto oh_my_gawd;
137
138 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
139 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
140
141 if (size == 1)
142 res = get_dbe(*value, (u8 *) addr);
143 else if (size == 2)
144 res = get_dbe(*value, (u16 *) addr);
145 else
146 res = get_dbe(*value, (u32 *) addr);
147
148 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
149
150oh_my_gawd:
151
152 /*
153 * IOC3 is fucked fucked beyond believe ... Don't even give the
154 * generic PCI code a chance to look at the wrong register.
155 */
156 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
157 *value = 0;
158 return PCIBIOS_SUCCESSFUL;
159 }
160
161 /*
162 * IOC3 is fucked fucked beyond believe ... Don't try to access
163 * anything but 32-bit words ...
164 */
165 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
166 addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
167
168 if (get_dbe(cf, (u32 *) addr))
169 return PCIBIOS_DEVICE_NOT_FOUND;
170
171 shift = ((where & 3) << 3);
172 mask = (0xffffffffU >> ((4 - size) << 3));
173 *value = (cf >> shift) & mask;
174
175 return PCIBIOS_SUCCESSFUL;
176}
177
178static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
179 int where, int size, u32 * value)
180{
181 if (bus->number > 0)
182 return pci_conf1_read_config(bus, devfn, where, size, value);
183
184 return pci_conf0_read_config(bus, devfn, where, size, value);
185}
186
187static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
188 int where, int size, u32 value)
189{
190 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
191 bridge_t *bridge = bc->base;
192 int slot = PCI_SLOT(devfn);
193 int fn = PCI_FUNC(devfn);
194 volatile void *addr;
195 u32 cf, shift, mask, smask;
196 int res;
197
198 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
199 if (get_dbe(cf, (u32 *) addr))
200 return PCIBIOS_DEVICE_NOT_FOUND;
201
202 /*
203 * IOC3 is fucked fucked beyond believe ... Don't even give the
204 * generic PCI code a chance to look at it for real ...
205 */
206 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
207 goto oh_my_gawd;
208
209 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
210
211 if (size == 1) {
212 res = put_dbe(value, (u8 *) addr);
213 } else if (size == 2) {
214 res = put_dbe(value, (u16 *) addr);
215 } else {
216 res = put_dbe(value, (u32 *) addr);
217 }
218
219 if (res)
220 return PCIBIOS_DEVICE_NOT_FOUND;
221
222 return PCIBIOS_SUCCESSFUL;
223
224oh_my_gawd:
225
226 /*
227 * IOC3 is fucked fucked beyond believe ... Don't even give the
228 * generic PCI code a chance to touch the wrong register.
229 */
230 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
231 return PCIBIOS_SUCCESSFUL;
232
233 /*
234 * IOC3 is fucked fucked beyond believe ... Don't try to access
235 * anything but 32-bit words ...
236 */
237 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
238
239 if (get_dbe(cf, (u32 *) addr))
240 return PCIBIOS_DEVICE_NOT_FOUND;
241
242 shift = ((where & 3) << 3);
243 mask = (0xffffffffU >> ((4 - size) << 3));
244 smask = mask << shift;
245
246 cf = (cf & ~smask) | ((value & mask) << shift);
247 if (put_dbe(cf, (u32 *) addr))
248 return PCIBIOS_DEVICE_NOT_FOUND;
249
250 return PCIBIOS_SUCCESSFUL;
251}
252
253static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
254 int where, int size, u32 value)
255{
256 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
257 bridge_t *bridge = bc->base;
258 int slot = PCI_SLOT(devfn);
259 int fn = PCI_FUNC(devfn);
260 int busno = bus->number;
261 volatile void *addr;
262 u32 cf, shift, mask, smask;
263 int res;
264
265 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
266 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
267 if (get_dbe(cf, (u32 *) addr))
268 return PCIBIOS_DEVICE_NOT_FOUND;
269
270 /*
271 * IOC3 is fucked fucked beyond believe ... Don't even give the
272 * generic PCI code a chance to look at it for real ...
273 */
274 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
275 goto oh_my_gawd;
276
277 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
278
279 if (size == 1) {
280 res = put_dbe(value, (u8 *) addr);
281 } else if (size == 2) {
282 res = put_dbe(value, (u16 *) addr);
283 } else {
284 res = put_dbe(value, (u32 *) addr);
285 }
286
287 if (res)
288 return PCIBIOS_DEVICE_NOT_FOUND;
289
290 return PCIBIOS_SUCCESSFUL;
291
292oh_my_gawd:
293
294 /*
295 * IOC3 is fucked fucked beyond believe ... Don't even give the
296 * generic PCI code a chance to touch the wrong register.
297 */
298 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
299 return PCIBIOS_SUCCESSFUL;
300
301 /*
302 * IOC3 is fucked fucked beyond believe ... Don't try to access
303 * anything but 32-bit words ...
304 */
305 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
306
307 if (get_dbe(cf, (u32 *) addr))
308 return PCIBIOS_DEVICE_NOT_FOUND;
309
310 shift = ((where & 3) << 3);
311 mask = (0xffffffffU >> ((4 - size) << 3));
312 smask = mask << shift;
313
314 cf = (cf & ~smask) | ((value & mask) << shift);
315 if (put_dbe(cf, (u32 *) addr))
316 return PCIBIOS_DEVICE_NOT_FOUND;
317
318 return PCIBIOS_SUCCESSFUL;
319}
320
321static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
322 int where, int size, u32 value)
323{
324 if (bus->number > 0)
325 return pci_conf1_write_config(bus, devfn, where, size, value);
326
327 return pci_conf0_write_config(bus, devfn, where, size, value);
328}
329
330static struct pci_ops bridge_pci_ops = {
331 .read = pci_read_config,
332 .write = pci_write_config,
333};
334
335int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid)
336{
337 unsigned long offset = NODE_OFFSET(nasid);
338 struct bridge_controller *bc;
339 static int num_bridges = 0;
340 bridge_t *bridge;
341 int slot;
342
343 printk("a bridge\n");
344
345 /* XXX: kludge alert.. */
346 if (!num_bridges)
347 ioport_resource.end = ~0UL;
348
349 bc = &bridges[num_bridges];
350
351 bc->pc.pci_ops = &bridge_pci_ops;
352 bc->pc.mem_resource = &bc->mem;
353 bc->pc.io_resource = &bc->io;
354
355 bc->pc.index = num_bridges;
356
357 bc->mem.name = "Bridge PCI MEM";
358 bc->pc.mem_offset = offset;
359 bc->mem.start = 0;
360 bc->mem.end = ~0UL;
361 bc->mem.flags = IORESOURCE_MEM;
362
363 bc->io.name = "Bridge IO MEM";
364 bc->pc.io_offset = offset;
365 bc->io.start = 0UL;
366 bc->io.end = ~0UL;
367 bc->io.flags = IORESOURCE_IO;
368
369 bc->irq_cpu = smp_processor_id();
370 bc->widget_id = widget_id;
371 bc->nasid = nasid;
372
373 bc->baddr = (u64)masterwid << 60;
374 bc->baddr |= (1UL << 56); /* Barrier set */
375
376 /*
377 * point to this bridge
378 */
379 bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id);
380
381 /*
382 * Clear all pending interrupts.
383 */
384 bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR;
385
386 /*
387 * Until otherwise set up, assume all interrupts are from slot 0
388 */
389 bridge->b_int_device = 0x0;
390
391 /*
392 * swap pio's to pci mem and io space (big windows)
393 */
394 bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP |
395 BRIDGE_CTRL_MEM_SWAP;
396
397 /*
398 * Hmm... IRIX sets additional bits in the address which
399 * are documented as reserved in the bridge docs.
400 */
401 bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
402 bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/
403 bridge->b_dir_map = (masterwid << 20); /* DMA */
404 bridge->b_int_enable = 0;
405
406 for (slot = 0; slot < 8; slot ++) {
407 bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
408 bc->pci_int[slot] = -1;
409 }
410 bridge->b_wid_tflush; /* wait until Bridge PIO complete */
411
412 bc->base = bridge;
413
414 register_pci_controller(&bc->pc);
415
416 num_bridges++;
417
418 return 0;
419}
420
421/*
422 * All observed requests have pin == 1. We could have a global here, that
423 * gets incremented and returned every time - unfortunately, pci_map_irq
424 * may be called on the same device over and over, and need to return the
425 * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
426 *
427 * A given PCI device, in general, should be able to intr any of the cpus
428 * on any one of the hubs connected to its xbow.
429 */
430int __devinit pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
431{
432 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
433 int irq = bc->pci_int[slot];
434
435 if (irq == -1) {
436 irq = bc->pci_int[slot] = request_bridge_irq(bc);
437 if (irq < 0)
438 panic("Can't allocate interrupt for PCI device %s\n",
439 pci_name(dev));
440 }
441
442 irq_to_bridge[irq] = bc;
443 irq_to_slot[irq] = slot;
444
445 return irq;
446}
447
448/* Do platform specific device initialization at pci_enable_device() time */
449int pcibios_plat_dev_init(struct pci_dev *dev)
450{
451 return 0;
452}
453
454/*
455 * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses
456 * to find the slot number in sense of the bridge device register.
457 * XXX This also means multiple devices might rely on conflicting bridge
458 * settings.
459 */
460
461static inline void pci_disable_swapping(struct pci_dev *dev)
462{
463 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
464 bridge_t *bridge = bc->base;
465 int slot = PCI_SLOT(dev->devfn);
466
467 /* Turn off byte swapping */
468 bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
469 bridge->b_widget.w_tflush; /* Flush */
470}
471
472static inline void pci_enable_swapping(struct pci_dev *dev)
473{
474 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
475 bridge_t *bridge = bc->base;
476 int slot = PCI_SLOT(dev->devfn);
477
478 /* Turn on byte swapping */
479 bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
480 bridge->b_widget.w_tflush; /* Flush */
481}
482
483static void __init pci_fixup_ioc3(struct pci_dev *d)
484{
485 pci_disable_swapping(d);
486}
487
488DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
489 pci_fixup_ioc3);
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
new file mode 100644
index 00000000000..1faeb034f06
--- /dev/null
+++ b/arch/mips/pci/pci-ip32.c
@@ -0,0 +1,145 @@
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 */
26static 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
86extern struct pci_ops mace_pci_ops;
87#ifdef CONFIG_MIPS64
88static 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};
94static 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
102static 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};
108static 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
116static 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
125static 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 ioport_resource.end = mace_pci_io_resource.end;
140 register_pci_controller(&mace_pci_controller);
141
142 return 0;
143}
144
145arch_initcall(mace_init);
diff --git a/arch/mips/pci/pci-jmr3927.c b/arch/mips/pci/pci-jmr3927.c
new file mode 100644
index 00000000000..95a028769e5
--- /dev/null
+++ b/arch/mips/pci/pci-jmr3927.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * Copyright (C) 2000-2001 Toshiba Corporation
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
20 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29#include <linux/types.h>
30#include <linux/pci.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33
34#include <asm/jmr3927/jmr3927.h>
35#include <asm/debug.h>
36
37struct resource pci_io_resource = {
38 "IO MEM",
39 0x1000, /* reserve regacy I/O space */
40 0x1000 + JMR3927_PCIIO_SIZE - 1,
41 IORESOURCE_IO
42};
43
44struct resource pci_mem_resource = {
45 "PCI MEM",
46 JMR3927_PCIMEM,
47 JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE - 1,
48 IORESOURCE_MEM
49};
50
51extern struct pci_ops jmr3927_pci_ops;
52
53struct pci_controller jmr3927_controller = {
54 .pci_ops = &jmr3927_pci_ops,
55 .io_resource = &pci_io_resource,
56 .mem_resource = &pci_mem_resource,
57 .mem_offset = JMR3927_PCIMEM;
58};
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
new file mode 100644
index 00000000000..ae3cc4b254b
--- /dev/null
+++ b/arch/mips/pci/pci-lasat.c
@@ -0,0 +1,95 @@
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, 04 Keith M Wesolowski
7 */
8#include <linux/kernel.h>
9#include <linux/init.h>
10#include <linux/interrupt.h>
11#include <linux/pci.h>
12#include <linux/types.h>
13#include <linux/interrupt.h>
14#include <linux/pci.h>
15#include <linux/delay.h>
16#include <asm/bootinfo.h>
17
18extern struct pci_ops nile4_pci_ops;
19extern struct pci_ops gt64120_pci_ops;
20static struct resource lasat_pci_mem_resource = {
21 .name = "LASAT PCI MEM",
22 .start = 0x18000000,
23 .end = 0x19FFFFFF,
24 .flags = IORESOURCE_MEM,
25};
26
27static struct resource lasat_pci_io_resource = {
28 .name = "LASAT PCI IO",
29 .start = 0x1a000000,
30 .end = 0x1bFFFFFF,
31 .flags = IORESOURCE_IO,
32};
33
34static struct pci_controller lasat_pci_controller = {
35 .mem_resource = &lasat_pci_mem_resource,
36 .io_resource = &lasat_pci_io_resource,
37};
38
39static int __init lasat_pci_setup(void)
40{
41 printk("PCI: starting\n");
42
43 switch (mips_machtype) {
44 case MACH_LASAT_100:
45 lasat_pci_controller.pci_ops = &gt64120_pci_ops;
46 break;
47 case MACH_LASAT_200:
48 lasat_pci_controller.pci_ops = &nile4_pci_ops;
49 break;
50 default:
51 panic("pcibios_init: mips_machtype incorrect");
52 }
53
54 register_pci_controller(&lasat_pci_controller);
55 return 0;
56}
57early_initcall(lasat_pci_setup);
58
59#define LASATINT_ETH1 0
60#define LASATINT_ETH0 1
61#define LASATINT_HDC 2
62#define LASATINT_COMP 3
63#define LASATINT_HDLC 4
64#define LASATINT_PCIA 5
65#define LASATINT_PCIB 6
66#define LASATINT_PCIC 7
67#define LASATINT_PCID 8
68
69int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
70{
71 switch (slot) {
72 case 1:
73 return LASATINT_PCIA; /* Expansion Module 0 */
74 case 2:
75 return LASATINT_PCIB; /* Expansion Module 1 */
76 case 3:
77 return LASATINT_PCIC; /* Expansion Module 2 */
78 case 4:
79 return LASATINT_ETH1; /* Ethernet 1 (LAN 2) */
80 case 5:
81 return LASATINT_ETH0; /* Ethernet 0 (LAN 1) */
82 case 6:
83 return LASATINT_HDC; /* IDE controller */
84 default:
85 return 0xff; /* Illegal */
86 }
87
88 return -1;
89}
90
91/* Do platform specific device initialization at pci_enable_device() time */
92int pcibios_plat_dev_init(struct pci_dev *dev)
93{
94 return 0;
95}
diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c
new file mode 100644
index 00000000000..1d84d36e034
--- /dev/null
+++ b/arch/mips/pci/pci-ocelot-c.c
@@ -0,0 +1,143 @@
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
9#include <linux/types.h>
10#include <linux/pci.h>
11#include <asm/mv64340.h>
12
13#include <linux/init.h>
14
15/*
16 * We assume the address ranges have already been setup appropriately by
17 * the firmware. PMON in case of the Ocelot C does that.
18 */
19static struct resource mv_pci_io_mem0_resource = {
20 .name = "MV64340 PCI0 IO MEM",
21 .flags = IORESOURCE_IO
22};
23
24static struct resource mv_pci_mem0_resource = {
25 .name = "MV64340 PCI0 MEM",
26 .flags = IORESOURCE_MEM
27};
28
29static struct mv_pci_controller mv_bus0_controller = {
30 .pcic = {
31 .pci_ops = &mv_pci_ops,
32 .mem_resource = &mv_pci_mem0_resource,
33 .io_resource = &mv_pci_io_mem0_resource,
34 },
35 .config_addr = MV64340_PCI_0_CONFIG_ADDR,
36 .config_vreg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
37};
38
39static uint32_t mv_io_base, mv_io_size;
40
41static void mv64340_pci0_init(void)
42{
43 uint32_t mem0_base, mem0_size;
44 uint32_t io_base, io_size;
45
46 io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
47 io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
48 mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
49 mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
50
51 mv_pci_io_mem0_resource.start = 0;
52 mv_pci_io_mem0_resource.end = io_size - 1;
53 mv_pci_mem0_resource.start = mem0_base;
54 mv_pci_mem0_resource.end = mem0_base + mem0_size - 1;
55 mv_bus0_controller.pcic.mem_offset = mem0_base;
56 mv_bus0_controller.pcic.io_offset = 0;
57
58 ioport_resource.end = io_size - 1;
59
60 register_pci_controller(&mv_bus0_controller.pcic);
61
62 mv_io_base = io_base;
63 mv_io_size = io_size;
64}
65
66static struct resource mv_pci_io_mem1_resource = {
67 .name = "MV64340 PCI1 IO MEM",
68 .flags = IORESOURCE_IO
69};
70
71static struct resource mv_pci_mem1_resource = {
72 .name = "MV64340 PCI1 MEM",
73 .flags = IORESOURCE_MEM
74};
75
76static struct mv_pci_controller mv_bus1_controller = {
77 .pcic = {
78 .pci_ops = &mv_pci_ops,
79 .mem_resource = &mv_pci_mem1_resource,
80 .io_resource = &mv_pci_io_mem1_resource,
81 },
82 .config_addr = MV64340_PCI_1_CONFIG_ADDR,
83 .config_vreg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
84};
85
86static __init void mv64340_pci1_init(void)
87{
88 uint32_t mem0_base, mem0_size;
89 uint32_t io_base, io_size;
90
91 io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
92 io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
93 mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
94 mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
95
96 /*
97 * Here we assume the I/O window of second bus to be contiguous with
98 * the first. A gap is no problem but would waste address space for
99 * remapping the port space.
100 */
101 mv_pci_io_mem1_resource.start = mv_io_size;
102 mv_pci_io_mem1_resource.end = mv_io_size + io_size - 1;
103 mv_pci_mem1_resource.start = mem0_base;
104 mv_pci_mem1_resource.end = mem0_base + mem0_size - 1;
105 mv_bus1_controller.pcic.mem_offset = mem0_base;
106 mv_bus1_controller.pcic.io_offset = 0;
107
108 ioport_resource.end = io_base + io_size -mv_io_base - 1;
109
110 register_pci_controller(&mv_bus1_controller.pcic);
111
112 mv_io_size = io_base + io_size - mv_io_base;
113}
114
115static __init int __init ocelot_c_pci_init(void)
116{
117 unsigned long io_v_base;
118 uint32_t enable;
119
120 enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
121
122 /*
123 * We require at least one enabled I/O or PCI memory window or we
124 * will ignore this PCI bus. We ignore PCI windows 1, 2 and 3.
125 */
126 if (enable & (0x01 << 9) || enable & (0x01 << 10))
127 mv64340_pci0_init();
128
129 if (enable & (0x01 << 14) || enable & (0x01 << 15))
130 mv64340_pci1_init();
131
132 if (mv_io_size) {
133 io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
134 if (!io_v_base)
135 panic("Could not ioremap I/O port range");
136
137 set_io_port_base(io_v_base);
138 }
139
140 return 0;
141}
142
143arch_initcall(ocelot_c_pci_init);
diff --git a/arch/mips/pci/pci-ocelot-g.c b/arch/mips/pci/pci-ocelot-g.c
new file mode 100644
index 00000000000..1e3430154fa
--- /dev/null
+++ b/arch/mips/pci/pci-ocelot-g.c
@@ -0,0 +1,97 @@
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 * This doesn't really fly - but I don't have a GT64240 system for testing.
9 */
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/pci.h>
14#include <asm/gt64240.h>
15
16/*
17 * We assume these address ranges have been programmed into the GT-64240 by
18 * the firmware. PMON in case of the Ocelot G does that. Note the size of
19 * the I/O range is completly stupid; I/O mappings are limited to at most
20 * 256 bytes by the PCI spec and deprecated; and just to make things worse
21 * apparently many devices don't decode more than 64k of I/O space.
22 */
23
24#define gt_io_size 0x20000000UL
25#define gt_io_base 0xe0000000UL
26
27static struct resource gt_pci_mem0_resource = {
28 .name = "MV64240 PCI0 MEM",
29 .start = 0xc0000000UL,
30 .end = 0xcfffffffUL,
31 .flags = IORESOURCE_MEM
32};
33
34static struct resource gt_pci_io_mem0_resource = {
35 .name = "MV64240 PCI0 IO MEM",
36 .start = 0xe0000000UL,
37 .end = 0xefffffffUL,
38 .flags = IORESOURCE_IO
39};
40
41static struct mv_pci_controller gt_bus0_controller = {
42 .pcic = {
43 .pci_ops = &mv_pci_ops,
44 .mem_resource = &gt_pci_mem0_resource,
45 .mem_offset = 0xc0000000UL,
46 .io_resource = &gt_pci_io_mem0_resource,
47 .io_offset = 0x00000000UL
48 },
49 .config_addr = PCI_0CONFIGURATION_ADDRESS,
50 .config_vreg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
51};
52
53static struct resource gt_pci_mem1_resource = {
54 .name = "MV64240 PCI1 MEM",
55 .start = 0xd0000000UL,
56 .end = 0xdfffffffUL,
57 .flags = IORESOURCE_MEM
58};
59
60static struct resource gt_pci_io_mem1_resource = {
61 .name = "MV64240 PCI1 IO MEM",
62 .start = 0xf0000000UL,
63 .end = 0xffffffffUL,
64 .flags = IORESOURCE_IO
65};
66
67static struct mv_pci_controller gt_bus1_controller = {
68 .pcic = {
69 .pci_ops = &mv_pci_ops,
70 .mem_resource = &gt_pci_mem1_resource,
71 .mem_offset = 0xd0000000UL,
72 .io_resource = &gt_pci_io_mem1_resource,
73 .io_offset = 0x10000000UL
74 },
75 .config_addr = PCI_1CONFIGURATION_ADDRESS,
76 .config_vreg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,
77};
78
79static __init int __init ocelot_g_pci_init(void)
80{
81 unsigned long io_v_base;
82
83 if (gt_io_size) {
84 io_v_base = (unsigned long) ioremap(gt_io_base, gt_io_size);
85 if (!io_v_base)
86 panic("Could not ioremap I/O port range");
87
88 set_io_port_base(io_v_base);
89 }
90
91 register_pci_controller(&gt_bus0_controller.pcic);
92 register_pci_controller(&gt_bus1_controller.pcic);
93
94 return 0;
95}
96
97arch_initcall(ocelot_g_pci_init);
diff --git a/arch/mips/pci/pci-ocelot.c b/arch/mips/pci/pci-ocelot.c
new file mode 100644
index 00000000000..3da8a4ee6ba
--- /dev/null
+++ b/arch/mips/pci/pci-ocelot.c
@@ -0,0 +1,107 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo Evaluation Boards PCI support.
4 *
5 * The general-purpose functions to read/write and configure the GT64120A's
6 * PCI registers (function names start with pci0 or pci1) are either direct
7 * copies of functions written by Galileo Technology, or are modifications
8 * of their functions to work with Linux 2.4 vs Linux 2.2. These functions
9 * are Copyright - Galileo Technology.
10 *
11 * Other functions are derived from other MIPS PCI implementations, or were
12 * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc.
13 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
14 *
15 * Copyright 2001 MontaVista Software Inc.
16 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2 of the License, or (at your
21 * option) any later version.
22 *
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
26 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
30 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * You should have received a copy of the GNU General Public License along
35 * with this program; if not, write to the Free Software Foundation, Inc.,
36 * 675 Mass Ave, Cambridge, MA 02139, USA.
37 */
38#include <linux/init.h>
39#include <linux/types.h>
40#include <linux/pci.h>
41#include <linux/kernel.h>
42#include <linux/slab.h>
43#include <linux/cache.h>
44#include <asm/pci.h>
45#include <asm/io.h>
46#include <asm/gt64120.h>
47
48static inline unsigned int pci0ReadConfigReg(unsigned int offset)
49{
50 unsigned int DataForRegCf8;
51 unsigned int data;
52
53 DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
54 (PCI_FUNC(device->devfn) << 8) |
55 (offset & ~0x3)) | 0x80000000;
56 GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
57 GT_READ(GT_PCI0_CFGDATA_OFS, &data);
58
59 return data;
60}
61
62static inline void pci0WriteConfigReg(unsigned int offset, unsigned int data)
63{
64 unsigned int DataForRegCf8;
65
66 DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
67 (PCI_FUNC(device->devfn) << 8) |
68 (offset & ~0x3)) | 0x80000000;
69 GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
70 GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
71}
72
73static struct resource ocelot_mem_resource = {
74 iomem_resource.start = GT_PCI_MEM_BASE;
75 iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1;
76};
77
78static struct resource ocelot_io_resource = {
79 ioport_resource.start = GT_PCI_IO_BASE;
80 ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
81};
82
83static struct pci_controller ocelot_pci_controller = {
84 .pci_ops = gt64120_pci_ops;
85 .mem_resource = &ocelot_mem_resource;
86 .io_resource = &ocelot_io_resource;
87};
88
89static int __init ocelot_pcibios_init(void)
90{
91 u32 tmp;
92
93 GT_READ(GT_PCI0_CMD_OFS, &tmp);
94 GT_READ(GT_PCI0_BARE_OFS, &tmp);
95
96 /*
97 * You have to enable bus mastering to configure any other
98 * card on the bus.
99 */
100 tmp = pci0ReadConfigReg(PCI_COMMAND);
101 tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
102 pci0WriteConfigReg(PCI_COMMAND, tmp);
103
104 register_pci_controller(&ocelot_pci_controller);
105}
106
107arch_initcall(ocelot_pcibios_init);
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
new file mode 100644
index 00000000000..7cca3bde59b
--- /dev/null
+++ b/arch/mips/pci/pci-sb1250.c
@@ -0,0 +1,292 @@
1/*
2 * Copyright (C) 2001,2002,2003 Broadcom Corporation
3 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * BCM1250-specific PCI support
22 *
23 * This module provides the glue between Linux's PCI subsystem
24 * and the hardware. We basically provide glue for accessing
25 * configuration space, and set up the translation for I/O
26 * space accesses.
27 *
28 * To access configuration space, we use ioremap. In the 32-bit
29 * kernel, this consumes either 4 or 8 page table pages, and 16MB of
30 * kernel mapped memory. Hopefully neither of these should be a huge
31 * problem.
32 */
33#include <linux/config.h>
34#include <linux/types.h>
35#include <linux/pci.h>
36#include <linux/kernel.h>
37#include <linux/init.h>
38#include <linux/mm.h>
39#include <linux/console.h>
40#include <linux/tty.h>
41
42#include <asm/io.h>
43
44#include <asm/sibyte/sb1250_defs.h>
45#include <asm/sibyte/sb1250_regs.h>
46#include <asm/sibyte/sb1250_scd.h>
47#include <asm/sibyte/board.h>
48
49/*
50 * Macros for calculating offsets into config space given a device
51 * structure or dev/fun/reg
52 */
53#define CFGOFFSET(bus,devfn,where) (((bus)<<16) + ((devfn)<<8) + (where))
54#define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where)
55
56static void *cfg_space;
57
58#define PCI_BUS_ENABLED 1
59#define LDT_BUS_ENABLED 2
60#define PCI_DEVICE_MODE 4
61
62static int sb1250_bus_status = 0;
63
64#define PCI_BRIDGE_DEVICE 0
65#define LDT_BRIDGE_DEVICE 1
66
67#ifdef CONFIG_SIBYTE_HAS_LDT
68/*
69 * HT's level-sensitive interrupts require EOI, which is generated
70 * through a 4MB memory-mapped region
71 */
72unsigned long ldt_eoi_space;
73#endif
74
75/*
76 * Read/write 32-bit values in config space.
77 */
78static inline u32 READCFG32(u32 addr)
79{
80 return *(u32 *) (cfg_space + (addr & ~3));
81}
82
83static inline void WRITECFG32(u32 addr, u32 data)
84{
85 *(u32 *) (cfg_space + (addr & ~3)) = data;
86}
87
88int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
89{
90 return dev->irq;
91}
92
93/* Do platform specific device initialization at pci_enable_device() time */
94int pcibios_plat_dev_init(struct pci_dev *dev)
95{
96 return 0;
97}
98
99/*
100 * Some checks before doing config cycles:
101 * In PCI Device Mode, hide everything on bus 0 except the LDT host
102 * bridge. Otherwise, access is controlled by bridge MasterEn bits.
103 */
104static int sb1250_pci_can_access(struct pci_bus *bus, int devfn)
105{
106 u32 devno;
107
108 if (!(sb1250_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
109 return 0;
110
111 if (bus->number == 0) {
112 devno = PCI_SLOT(devfn);
113 if (devno == LDT_BRIDGE_DEVICE)
114 return (sb1250_bus_status & LDT_BUS_ENABLED) != 0;
115 else if (sb1250_bus_status & PCI_DEVICE_MODE)
116 return 0;
117 else
118 return 1;
119 } else
120 return 1;
121}
122
123/*
124 * Read/write access functions for various sizes of values
125 * in config space. Return all 1's for disallowed accesses
126 * for a kludgy but adequate simulation of master aborts.
127 */
128
129static int sb1250_pcibios_read(struct pci_bus *bus, unsigned int devfn,
130 int where, int size, u32 * val)
131{
132 u32 data = 0;
133
134 if ((size == 2) && (where & 1))
135 return PCIBIOS_BAD_REGISTER_NUMBER;
136 else if ((size == 4) && (where & 3))
137 return PCIBIOS_BAD_REGISTER_NUMBER;
138
139 if (sb1250_pci_can_access(bus, devfn))
140 data = READCFG32(CFGADDR(bus, devfn, where));
141 else
142 data = 0xFFFFFFFF;
143
144 if (size == 1)
145 *val = (data >> ((where & 3) << 3)) & 0xff;
146 else if (size == 2)
147 *val = (data >> ((where & 3) << 3)) & 0xffff;
148 else
149 *val = data;
150
151 return PCIBIOS_SUCCESSFUL;
152}
153
154static int sb1250_pcibios_write(struct pci_bus *bus, unsigned int devfn,
155 int where, int size, u32 val)
156{
157 u32 cfgaddr = CFGADDR(bus, devfn, where);
158 u32 data = 0;
159
160 if ((size == 2) && (where & 1))
161 return PCIBIOS_BAD_REGISTER_NUMBER;
162 else if ((size == 4) && (where & 3))
163 return PCIBIOS_BAD_REGISTER_NUMBER;
164
165 if (!sb1250_pci_can_access(bus, devfn))
166 return PCIBIOS_BAD_REGISTER_NUMBER;
167
168 data = READCFG32(cfgaddr);
169
170 if (size == 1)
171 data = (data & ~(0xff << ((where & 3) << 3))) |
172 (val << ((where & 3) << 3));
173 else if (size == 2)
174 data = (data & ~(0xffff << ((where & 3) << 3))) |
175 (val << ((where & 3) << 3));
176 else
177 data = val;
178
179 WRITECFG32(cfgaddr, data);
180
181 return PCIBIOS_SUCCESSFUL;
182}
183
184struct pci_ops sb1250_pci_ops = {
185 .read = sb1250_pcibios_read,
186 .write = sb1250_pcibios_write,
187};
188
189static struct resource sb1250_mem_resource = {
190 .name = "SB1250 PCI MEM",
191 .start = 0x40000000UL,
192 .end = 0x5fffffffUL,
193 .flags = IORESOURCE_MEM,
194};
195
196static struct resource sb1250_io_resource = {
197 .name = "SB1250 PCI I/O",
198 .start = 0x00000000UL,
199 .end = 0x01ffffffUL,
200 .flags = IORESOURCE_IO,
201};
202
203struct pci_controller sb1250_controller = {
204 .pci_ops = &sb1250_pci_ops,
205 .mem_resource = &sb1250_mem_resource,
206 .io_resource = &sb1250_io_resource,
207};
208
209static int __init sb1250_pcibios_init(void)
210{
211 uint32_t cmdreg;
212 uint64_t reg;
213 extern int pci_probe_only;
214
215 /* CFE will assign PCI resources */
216 pci_probe_only = 1;
217
218 /* Avoid ISA compat ranges. */
219 PCIBIOS_MIN_IO = 0x00008000UL;
220 PCIBIOS_MIN_MEM = 0x01000000UL;
221
222 /* Set I/O resource limits. */
223 ioport_resource.end = 0x01ffffffUL; /* 32MB accessible by sb1250 */
224 iomem_resource.end = 0xffffffffUL; /* no HT support yet */
225
226 cfg_space =
227 ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16 * 1024 * 1024);
228
229 /*
230 * See if the PCI bus has been configured by the firmware.
231 */
232 reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG));
233 if (!(reg & M_SYS_PCI_HOST)) {
234 sb1250_bus_status |= PCI_DEVICE_MODE;
235 } else {
236 cmdreg =
237 READCFG32(CFGOFFSET
238 (0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
239 PCI_COMMAND));
240 if (!(cmdreg & PCI_COMMAND_MASTER)) {
241 printk
242 ("PCI: Skipping PCI probe. Bus is not initialized.\n");
243 iounmap(cfg_space);
244 return 0;
245 }
246 sb1250_bus_status |= PCI_BUS_ENABLED;
247 }
248
249 /*
250 * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
251 * space. Use "match bytes" policy to make everything look
252 * little-endian. So, you need to also set
253 * CONFIG_SWAP_IO_SPACE, but this is the combination that
254 * works correctly with most of Linux's drivers.
255 * XXX ehs: Should this happen in PCI Device mode?
256 */
257
258 set_io_port_base((unsigned long)
259 ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536));
260 isa_slot_offset = (unsigned long)
261 ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024 * 1024);
262
263#ifdef CONFIG_SIBYTE_HAS_LDT
264 /*
265 * Also check the LDT bridge's enable, just in case we didn't
266 * initialize that one.
267 */
268
269 cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(LDT_BRIDGE_DEVICE, 0),
270 PCI_COMMAND));
271 if (cmdreg & PCI_COMMAND_MASTER) {
272 sb1250_bus_status |= LDT_BUS_ENABLED;
273
274 /*
275 * Need bits 23:16 to convey vector number. Note that
276 * this consumes 4MB of kernel-mapped memory
277 * (Kseg2/Kseg3) for 32-bit kernel.
278 */
279 ldt_eoi_space = (unsigned long)
280 ioremap(A_PHYS_LDT_SPECIAL_MATCH_BYTES,
281 4 * 1024 * 1024);
282 }
283#endif
284
285 register_pci_controller(&sb1250_controller);
286
287#ifdef CONFIG_VGA_CONSOLE
288 take_over_console(&vga_con, 0, MAX_NR_CONSOLES - 1, 1);
289#endif
290 return 0;
291}
292arch_initcall(sb1250_pcibios_init);
diff --git a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c
new file mode 100644
index 00000000000..f3ccbf7fada
--- /dev/null
+++ b/arch/mips/pci/pci-vr41xx.c
@@ -0,0 +1,291 @@
1/*
2 * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series.
3 *
4 * Copyright (C) 2001-2003 MontaVista Software Inc.
5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6 * Copyright (C) 2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23/*
24 * Changes:
25 * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
26 * - New creation, NEC VR4122 and VR4131 are supported.
27 */
28#include <linux/init.h>
29#include <linux/pci.h>
30#include <linux/types.h>
31
32#include <asm/cpu.h>
33#include <asm/io.h>
34#include <asm/vr41xx/vr41xx.h>
35
36#include "pci-vr41xx.h"
37
38extern struct pci_ops vr41xx_pci_ops;
39
40static struct pci_master_address_conversion pci_master_memory1 = {
41 .bus_base_address = PCI_MASTER_MEM1_BUS_BASE_ADDRESS,
42 .address_mask = PCI_MASTER_MEM1_ADDRESS_MASK,
43 .pci_base_address = PCI_MASTER_MEM1_PCI_BASE_ADDRESS,
44};
45
46static struct pci_target_address_conversion pci_target_memory1 = {
47 .address_mask = PCI_TARGET_MEM1_ADDRESS_MASK,
48 .bus_base_address = PCI_TARGET_MEM1_BUS_BASE_ADDRESS,
49};
50
51static struct pci_master_address_conversion pci_master_io = {
52 .bus_base_address = PCI_MASTER_IO_BUS_BASE_ADDRESS,
53 .address_mask = PCI_MASTER_IO_ADDRESS_MASK,
54 .pci_base_address = PCI_MASTER_IO_PCI_BASE_ADDRESS,
55};
56
57static struct pci_mailbox_address pci_mailbox = {
58 .base_address = PCI_MAILBOX_BASE_ADDRESS,
59};
60
61static struct pci_target_address_window pci_target_window1 = {
62 .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS,
63};
64
65static struct resource pci_mem_resource = {
66 .name = "PCI Memory resources",
67 .start = PCI_MEM_RESOURCE_START,
68 .end = PCI_MEM_RESOURCE_END,
69 .flags = IORESOURCE_MEM,
70};
71
72static struct resource pci_io_resource = {
73 .name = "PCI I/O resources",
74 .start = PCI_IO_RESOURCE_START,
75 .end = PCI_IO_RESOURCE_END,
76 .flags = IORESOURCE_IO,
77};
78
79static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = {
80 .master_memory1 = &pci_master_memory1,
81 .target_memory1 = &pci_target_memory1,
82 .master_io = &pci_master_io,
83 .exclusive_access = CANNOT_LOCK_FROM_DEVICE,
84 .wait_time_limit_from_irdy_to_trdy = 0,
85 .mailbox = &pci_mailbox,
86 .target_window1 = &pci_target_window1,
87 .master_latency_timer = 0x80,
88 .retry_limit = 0,
89 .arbiter_priority_control = PCI_ARBITRATION_MODE_FAIR,
90 .take_away_gnt_mode = PCI_TAKE_AWAY_GNT_DISABLE,
91};
92
93static struct pci_controller vr41xx_pci_controller = {
94 .pci_ops = &vr41xx_pci_ops,
95 .mem_resource = &pci_mem_resource,
96 .io_resource = &pci_io_resource,
97};
98
99void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup)
100{
101 vr41xx_pci_controller_unit_setup = *setup;
102}
103
104static int __init vr41xx_pciu_init(void)
105{
106 struct pci_controller_unit_setup *setup;
107 struct pci_master_address_conversion *master;
108 struct pci_target_address_conversion *target;
109 struct pci_mailbox_address *mailbox;
110 struct pci_target_address_window *window;
111 unsigned long vtclock, pci_clock_max;
112 uint32_t val;
113
114 setup = &vr41xx_pci_controller_unit_setup;
115
116 /* Disable PCI interrupt */
117 vr41xx_disable_pciint();
118
119 /* Supply VTClock to PCIU */
120 vr41xx_supply_clock(PCIU_CLOCK);
121
122 /* Dummy write, waiting for supply of VTClock. */
123 vr41xx_disable_pciint();
124
125 /* Select PCI clock */
126 if (setup->pci_clock_max != 0)
127 pci_clock_max = setup->pci_clock_max;
128 else
129 pci_clock_max = PCI_CLOCK_MAX;
130 vtclock = vr41xx_get_vtclock_frequency();
131 if (vtclock < pci_clock_max)
132 writel(EQUAL_VTCLOCK, PCICLKSELREG);
133 else if ((vtclock / 2) < pci_clock_max)
134 writel(HALF_VTCLOCK, PCICLKSELREG);
135 else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 &&
136 (vtclock / 3) < pci_clock_max)
137 writel(ONE_THIRD_VTCLOCK, PCICLKSELREG);
138 else if ((vtclock / 4) < pci_clock_max)
139 writel(QUARTER_VTCLOCK, PCICLKSELREG);
140 else {
141 printk(KERN_ERR "PCI Clock is over 33MHz.\n");
142 return -EINVAL;
143 }
144
145 /* Supply PCI clock by PCI bus */
146 vr41xx_supply_clock(PCI_CLOCK);
147
148 if (setup->master_memory1 != NULL) {
149 master = setup->master_memory1;
150 val = IBA(master->bus_base_address) |
151 MASTER_MSK(master->address_mask) |
152 WINEN |
153 PCIA(master->pci_base_address);
154 writel(val, PCIMMAW1REG);
155 } else {
156 val = readl(PCIMMAW1REG);
157 val &= ~WINEN;
158 writel(val, PCIMMAW1REG);
159 }
160
161 if (setup->master_memory2 != NULL) {
162 master = setup->master_memory2;
163 val = IBA(master->bus_base_address) |
164 MASTER_MSK(master->address_mask) |
165 WINEN |
166 PCIA(master->pci_base_address);
167 writel(val, PCIMMAW2REG);
168 } else {
169 val = readl(PCIMMAW2REG);
170 val &= ~WINEN;
171 writel(val, PCIMMAW2REG);
172 }
173
174 if (setup->target_memory1 != NULL) {
175 target = setup->target_memory1;
176 val = TARGET_MSK(target->address_mask) |
177 WINEN |
178 ITA(target->bus_base_address);
179 writel(val, PCITAW1REG);
180 } else {
181 val = readl(PCITAW1REG);
182 val &= ~WINEN;
183 writel(val, PCITAW1REG);
184 }
185
186 if (setup->target_memory2 != NULL) {
187 target = setup->target_memory2;
188 val = TARGET_MSK(target->address_mask) |
189 WINEN |
190 ITA(target->bus_base_address);
191 writel(val, PCITAW2REG);
192 } else {
193 val = readl(PCITAW2REG);
194 val &= ~WINEN;
195 writel(val, PCITAW2REG);
196 }
197
198 if (setup->master_io != NULL) {
199 master = setup->master_io;
200 val = IBA(master->bus_base_address) |
201 MASTER_MSK(master->address_mask) |
202 WINEN |
203 PCIIA(master->pci_base_address);
204 writel(val, PCIMIOAWREG);
205 } else {
206 val = readl(PCIMIOAWREG);
207 val &= ~WINEN;
208 writel(val, PCIMIOAWREG);
209 }
210
211 if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE)
212 writel(UNLOCK, PCIEXACCREG);
213 else
214 writel(0, PCIEXACCREG);
215
216 if (current_cpu_data.cputype == CPU_VR4122)
217 writel(TRDYV(setup->wait_time_limit_from_irdy_to_trdy), PCITRDYVREG);
218
219 writel(MLTIM(setup->master_latency_timer), LATTIMEREG);
220
221 if (setup->mailbox != NULL) {
222 mailbox = setup->mailbox;
223 val = MBADD(mailbox->base_address) | TYPE_32BITSPACE |
224 MSI_MEMORY | PREF_APPROVAL;
225 writel(val, MAILBAREG);
226 }
227
228 if (setup->target_window1) {
229 window = setup->target_window1;
230 val = PMBA(window->base_address) | TYPE_32BITSPACE |
231 MSI_MEMORY | PREF_APPROVAL;
232 writel(val, PCIMBA1REG);
233 }
234
235 if (setup->target_window2) {
236 window = setup->target_window2;
237 val = PMBA(window->base_address) | TYPE_32BITSPACE |
238 MSI_MEMORY | PREF_APPROVAL;
239 writel(val, PCIMBA2REG);
240 }
241
242 val = readl(RETVALREG);
243 val &= ~RTYVAL_MASK;
244 val |= RTYVAL(setup->retry_limit);
245 writel(val, RETVALREG);
246
247 val = readl(PCIAPCNTREG);
248 val &= ~(TKYGNT | PAPC);
249
250 switch (setup->arbiter_priority_control) {
251 case PCI_ARBITRATION_MODE_ALTERNATE_0:
252 val |= PAPC_ALTERNATE_0;
253 break;
254 case PCI_ARBITRATION_MODE_ALTERNATE_B:
255 val |= PAPC_ALTERNATE_B;
256 break;
257 default:
258 val |= PAPC_FAIR;
259 break;
260 }
261
262 if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE)
263 val |= TKYGNT_ENABLE;
264
265 writel(val, PCIAPCNTREG);
266
267 writel(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
268 PCI_COMMAND_PARITY | PCI_COMMAND_SERR, COMMANDREG);
269
270 /* Clear bus error */
271 readl(BUSERRADREG);
272
273 writel(BLOODY_CONFIG_DONE, PCIENREG);
274
275 if (setup->mem_resource != NULL)
276 vr41xx_pci_controller.mem_resource = setup->mem_resource;
277
278 if (setup->io_resource != NULL) {
279 vr41xx_pci_controller.io_resource = setup->io_resource;
280 } else {
281 set_io_port_base(IO_PORT_BASE);
282 ioport_resource.start = IO_PORT_RESOURCE_START;
283 ioport_resource.end = IO_PORT_RESOURCE_END;
284 }
285
286 register_pci_controller(&vr41xx_pci_controller);
287
288 return 0;
289}
290
291arch_initcall(vr41xx_pciu_init);
diff --git a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h
new file mode 100644
index 00000000000..23815c8b903
--- /dev/null
+++ b/arch/mips/pci/pci-vr41xx.h
@@ -0,0 +1,151 @@
1/*
2 * pci-vr41xx.h, Include file for PCI Control Unit of the NEC VR4100 series.
3 *
4 * Copyright (C) 2002 MontaVista Software Inc.
5 * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
6 * Copyright (C) 2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#ifndef __PCI_VR41XX_H
23#define __PCI_VR41XX_H
24
25#define PCIMMAW1REG KSEG1ADDR(0x0f000c00)
26#define PCIMMAW2REG KSEG1ADDR(0x0f000c04)
27#define PCITAW1REG KSEG1ADDR(0x0f000c08)
28#define PCITAW2REG KSEG1ADDR(0x0f000c0c)
29#define PCIMIOAWREG KSEG1ADDR(0x0f000c10)
30 #define IBA(addr) ((addr) & 0xff000000U)
31 #define MASTER_MSK(mask) (((mask) >> 11) & 0x000fe000U)
32 #define PCIA(addr) (((addr) >> 24) & 0x000000ffU)
33 #define TARGET_MSK(mask) (((mask) >> 8) & 0x000fe000U)
34 #define ITA(addr) (((addr) >> 24) & 0x000000ffU)
35 #define PCIIA(addr) (((addr) >> 24) & 0x000000ffU)
36 #define WINEN 0x1000U
37#define PCICONFDREG KSEG1ADDR(0x0f000c14)
38#define PCICONFAREG KSEG1ADDR(0x0f000c18)
39#define PCIMAILREG KSEG1ADDR(0x0f000c1c)
40#define BUSERRADREG KSEG1ADDR(0x0f000c24)
41 #define EA(reg) ((reg) &0xfffffffc)
42
43#define INTCNTSTAREG KSEG1ADDR(0x0f000c28)
44 #define MABTCLR 0x80000000U
45 #define TRDYCLR 0x40000000U
46 #define PARCLR 0x20000000U
47 #define MBCLR 0x10000000U
48 #define SERRCLR 0x08000000U
49 #define RTYCLR 0x04000000U
50 #define MABCLR 0x02000000U
51 #define TABCLR 0x01000000U
52 /* RFU */
53 #define MABTMSK 0x00008000U
54 #define TRDYMSK 0x00004000U
55 #define PARMSK 0x00002000U
56 #define MBMSK 0x00001000U
57 #define SERRMSK 0x00000800U
58 #define RTYMSK 0x00000400U
59 #define MABMSK 0x00000200U
60 #define TABMSK 0x00000100U
61 #define IBAMABT 0x00000080U
62 #define TRDYRCH 0x00000040U
63 #define PAR 0x00000020U
64 #define MB 0x00000010U
65 #define PCISERR 0x00000008U
66 #define RTYRCH 0x00000004U
67 #define MABORT 0x00000002U
68 #define TABORT 0x00000001U
69
70#define PCIEXACCREG KSEG1ADDR(0x0f000c2c)
71 #define UNLOCK 0x2U
72 #define EAREQ 0x1U
73#define PCIRECONTREG KSEG1ADDR(0x0f000c30)
74 #define RTRYCNT(reg) ((reg) & 0x000000ffU)
75#define PCIENREG KSEG1ADDR(0x0f000c34)
76 #define BLOODY_CONFIG_DONE 0x4U
77#define PCICLKSELREG KSEG1ADDR(0x0f000c38)
78 #define EQUAL_VTCLOCK 0x2U
79 #define HALF_VTCLOCK 0x0U
80 #define ONE_THIRD_VTCLOCK 0x3U
81 #define QUARTER_VTCLOCK 0x1U
82#define PCITRDYVREG KSEG1ADDR(0x0f000c3c)
83 #define TRDYV(val) ((uint32_t)(val) & 0xffU)
84#define PCICLKRUNREG KSEG1ADDR(0x0f000c60)
85
86#define VENDORIDREG KSEG1ADDR(0x0f000d00)
87#define DEVICEIDREG KSEG1ADDR(0x0f000d00)
88#define COMMANDREG KSEG1ADDR(0x0f000d04)
89#define STATUSREG KSEG1ADDR(0x0f000d04)
90#define REVIDREG KSEG1ADDR(0x0f000d08)
91#define CLASSREG KSEG1ADDR(0x0f000d08)
92#define CACHELSREG KSEG1ADDR(0x0f000d0c)
93#define LATTIMEREG KSEG1ADDR(0x0f000d0c)
94 #define MLTIM(val) (((uint32_t)(val) << 7) & 0xff00U)
95#define MAILBAREG KSEG1ADDR(0x0f000d10)
96#define PCIMBA1REG KSEG1ADDR(0x0f000d14)
97#define PCIMBA2REG KSEG1ADDR(0x0f000d18)
98 #define MBADD(base) ((base) & 0xfffff800U)
99 #define PMBA(base) ((base) & 0xffe00000U)
100 #define PREF 0x8U
101 #define PREF_APPROVAL 0x8U
102 #define PREF_DISAPPROVAL 0x0U
103 #define TYPE 0x6U
104 #define TYPE_32BITSPACE 0x0U
105 #define MSI 0x1U
106 #define MSI_MEMORY 0x0U
107#define INTLINEREG KSEG1ADDR(0x0f000d3c)
108#define INTPINREG KSEG1ADDR(0x0f000d3c)
109#define RETVALREG KSEG1ADDR(0x0f000d40)
110#define PCIAPCNTREG KSEG1ADDR(0x0f000d40)
111 #define TKYGNT 0x04000000U
112 #define TKYGNT_ENABLE 0x04000000U
113 #define TKYGNT_DISABLE 0x00000000U
114 #define PAPC 0x03000000U
115 #define PAPC_ALTERNATE_B 0x02000000U
116 #define PAPC_ALTERNATE_0 0x01000000U
117 #define PAPC_FAIR 0x00000000U
118 #define RTYVAL(val) (((uint32_t)(val) << 7) & 0xff00U)
119 #define RTYVAL_MASK 0xff00U
120
121#define PCI_CLOCK_MAX 33333333U
122
123/*
124 * Default setup
125 */
126#define PCI_MASTER_MEM1_BUS_BASE_ADDRESS 0x10000000U
127#define PCI_MASTER_MEM1_ADDRESS_MASK 0x7c000000U
128#define PCI_MASTER_MEM1_PCI_BASE_ADDRESS 0x10000000U
129
130#define PCI_TARGET_MEM1_ADDRESS_MASK 0x08000000U
131#define PCI_TARGET_MEM1_BUS_BASE_ADDRESS 0x00000000U
132
133#define PCI_MASTER_IO_BUS_BASE_ADDRESS 0x16000000U
134#define PCI_MASTER_IO_ADDRESS_MASK 0x7e000000U
135#define PCI_MASTER_IO_PCI_BASE_ADDRESS 0x00000000U
136
137#define PCI_MAILBOX_BASE_ADDRESS 0x00000000U
138
139#define PCI_TARGET_WINDOW1_BASE_ADDRESS 0x00000000U
140
141#define IO_PORT_BASE KSEG1ADDR(PCI_MASTER_IO_BUS_BASE_ADDRESS)
142#define IO_PORT_RESOURCE_START PCI_MASTER_IO_PCI_BASE_ADDRESS
143#define IO_PORT_RESOURCE_END (~PCI_MASTER_IO_ADDRESS_MASK & PCI_MASTER_ADDRESS_MASK)
144
145#define PCI_IO_RESOURCE_START 0x01000000UL
146#define PCI_IO_RESOURCE_END 0x01ffffffUL
147
148#define PCI_MEM_RESOURCE_START 0x11000000UL
149#define PCI_MEM_RESOURCE_END 0x13ffffffUL
150
151#endif /* __PCI_VR41XX_H */
diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c
new file mode 100644
index 00000000000..dac9ed4b0cc
--- /dev/null
+++ b/arch/mips/pci/pci-yosemite.c
@@ -0,0 +1,60 @@
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 "Titan PCI MEM", 0xe0000000UL, 0xe3ffffffUL, IORESOURCE_MEM
18};
19
20/*
21 * PMON really reserves 16MB of I/O port space but that's stupid, nothing
22 * needs that much since allocations are limited to 256 bytes per device
23 * anyway. So we just claim 64kB here.
24 */
25#define TITAN_IO_SIZE 0x0000ffffUL
26#define TITAN_IO_BASE 0xe8000000UL
27
28static struct resource py_io_resource = {
29 "Titan IO MEM", 0x00001000UL, TITAN_IO_SIZE - 1, IORESOURCE_IO,
30};
31
32static struct pci_controller py_controller = {
33 .pci_ops = &titan_pci_ops,
34 .mem_resource = &py_mem_resource,
35 .mem_offset = 0x00000000UL,
36 .io_resource = &py_io_resource,
37 .io_offset = 0x00000000UL
38};
39
40static char ioremap_failed[] __initdata = "Could not ioremap I/O port range";
41
42static int __init pmc_yosemite_setup(void)
43{
44 unsigned long io_v_base;
45
46 io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
47 if (!io_v_base)
48 panic(ioremap_failed);
49
50 set_io_port_base(io_v_base);
51 TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
52
53 ioport_resource.end = TITAN_IO_SIZE - 1;
54
55 register_pci_controller(&py_controller);
56
57 return 0;
58}
59
60arch_initcall(pmc_yosemite_setup);
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
new file mode 100644
index 00000000000..8141dffac24
--- /dev/null
+++ b/arch/mips/pci/pci.c
@@ -0,0 +1,304 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation; either version 2 of the License, or (at your
5 * option) any later version.
6 *
7 * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org)
8 */
9#include <linux/config.h>
10#include <linux/kernel.h>
11#include <linux/mm.h>
12#include <linux/bootmem.h>
13#include <linux/init.h>
14#include <linux/types.h>
15#include <linux/pci.h>
16
17/*
18 * Indicate whether we respect the PCI setup left by the firmware.
19 *
20 * Make this long-lived so that we know when shutting down
21 * whether we probed only or not.
22 */
23int pci_probe_only;
24
25#define PCI_ASSIGN_ALL_BUSSES 1
26
27unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES;
28
29/*
30 * The PCI controller list.
31 */
32
33struct pci_controller *hose_head, **hose_tail = &hose_head;
34struct pci_controller *pci_isa_hose;
35
36unsigned long PCIBIOS_MIN_IO = 0x0000;
37unsigned long PCIBIOS_MIN_MEM = 0;
38
39/*
40 * We need to avoid collisions with `mirrored' VGA ports
41 * and other strange ISA hardware, so we always want the
42 * addresses to be allocated in the 0x000-0x0ff region
43 * modulo 0x400.
44 *
45 * Why? Because some silly external IO cards only decode
46 * the low 10 bits of the IO address. The 0x00-0xff region
47 * is reserved for motherboard devices that decode all 16
48 * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
49 * but we want to try to avoid allocating at 0x2900-0x2bff
50 * which might have be mirrored at 0x0100-0x03ff..
51 */
52void
53pcibios_align_resource(void *data, struct resource *res,
54 unsigned long size, unsigned long align)
55{
56 struct pci_dev *dev = data;
57 struct pci_controller *hose = dev->sysdata;
58 unsigned long start = res->start;
59
60 if (res->flags & IORESOURCE_IO) {
61 /* Make sure we start at our min on all hoses */
62 if (start < PCIBIOS_MIN_IO + hose->io_resource->start)
63 start = PCIBIOS_MIN_IO + hose->io_resource->start;
64
65 /*
66 * Put everything into 0x00-0xff region modulo 0x400
67 */
68 if (start & 0x300)
69 start = (start + 0x3ff) & ~0x3ff;
70 } else if (res->flags & IORESOURCE_MEM) {
71 /* Make sure we start at our min on all hoses */
72 if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start)
73 start = PCIBIOS_MIN_MEM + hose->mem_resource->start;
74 }
75
76 res->start = start;
77}
78
79struct pci_controller * __init alloc_pci_controller(void)
80{
81 return alloc_bootmem(sizeof(struct pci_controller));
82}
83
84void __init register_pci_controller(struct pci_controller *hose)
85{
86 *hose_tail = hose;
87 hose_tail = &hose->next;
88}
89
90/* Most MIPS systems have straight-forward swizzling needs. */
91
92static inline u8 bridge_swizzle(u8 pin, u8 slot)
93{
94 return (((pin - 1) + slot) % 4) + 1;
95}
96
97static u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
98{
99 u8 pin = *pinp;
100
101 while (dev->bus->parent) {
102 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
103 /* Move up the chain of bridges. */
104 dev = dev->bus->self;
105 }
106 *pinp = pin;
107
108 /* The slot is the slot of the last bridge. */
109 return PCI_SLOT(dev->devfn);
110}
111
112static int __init pcibios_init(void)
113{
114 struct pci_controller *hose;
115 struct pci_bus *bus;
116 int next_busno;
117 int need_domain_info = 0;
118
119 /* Scan all of the recorded PCI controllers. */
120 for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
121
122 if (request_resource(&iomem_resource, hose->mem_resource) < 0)
123 goto out;
124 if (request_resource(&ioport_resource, hose->io_resource) < 0)
125 goto out_free_mem_resource;
126
127 if (!hose->iommu)
128 PCI_DMA_BUS_IS_PHYS = 1;
129
130 bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
131 hose->bus = bus;
132 hose->need_domain_info = need_domain_info;
133 next_busno = bus->subordinate + 1;
134 /* Don't allow 8-bit bus number overflow inside the hose -
135 reserve some space for bridges. */
136 if (next_busno > 224) {
137 next_busno = 0;
138 need_domain_info = 1;
139 }
140 continue;
141
142out_free_mem_resource:
143 release_resource(hose->mem_resource);
144
145out:
146 printk(KERN_WARNING
147 "Skipping PCI bus scan due to resource conflict\n");
148 }
149
150 if (!pci_probe_only)
151 pci_assign_unassigned_resources();
152 pci_fixup_irqs(common_swizzle, pcibios_map_irq);
153
154 return 0;
155}
156
157subsys_initcall(pcibios_init);
158
159static int pcibios_enable_resources(struct pci_dev *dev, int mask)
160{
161 u16 cmd, old_cmd;
162 int idx;
163 struct resource *r;
164
165 pci_read_config_word(dev, PCI_COMMAND, &cmd);
166 old_cmd = cmd;
167 for(idx=0; idx<6; idx++) {
168 /* Only set up the requested stuff */
169 if (!(mask & (1<<idx)))
170 continue;
171
172 r = &dev->resource[idx];
173 if (!r->start && r->end) {
174 printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
175 return -EINVAL;
176 }
177 if (r->flags & IORESOURCE_IO)
178 cmd |= PCI_COMMAND_IO;
179 if (r->flags & IORESOURCE_MEM)
180 cmd |= PCI_COMMAND_MEMORY;
181 }
182 if (dev->resource[PCI_ROM_RESOURCE].start)
183 cmd |= PCI_COMMAND_MEMORY;
184 if (cmd != old_cmd) {
185 printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
186 pci_write_config_word(dev, PCI_COMMAND, cmd);
187 }
188 return 0;
189}
190
191/*
192 * If we set up a device for bus mastering, we need to check the latency
193 * timer as certain crappy BIOSes forget to set it properly.
194 */
195unsigned int pcibios_max_latency = 255;
196
197void pcibios_set_master(struct pci_dev *dev)
198{
199 u8 lat;
200 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
201 if (lat < 16)
202 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
203 else if (lat > pcibios_max_latency)
204 lat = pcibios_max_latency;
205 else
206 return;
207 printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
208 pci_name(dev), lat);
209 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
210}
211
212unsigned int pcibios_assign_all_busses(void)
213{
214 return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
215}
216
217int pcibios_enable_device(struct pci_dev *dev, int mask)
218{
219 int err;
220
221 if ((err = pcibios_enable_resources(dev, mask)) < 0)
222 return err;
223
224 return pcibios_plat_dev_init(dev);
225}
226
227static void __init pcibios_fixup_device_resources(struct pci_dev *dev,
228 struct pci_bus *bus)
229{
230 /* Update device resources. */
231 struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
232 unsigned long offset = 0;
233 int i;
234
235 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
236 if (!dev->resource[i].start)
237 continue;
238 if (dev->resource[i].flags & IORESOURCE_IO)
239 offset = hose->io_offset;
240 else if (dev->resource[i].flags & IORESOURCE_MEM)
241 offset = hose->mem_offset;
242
243 dev->resource[i].start += offset;
244 dev->resource[i].end += offset;
245 }
246}
247
248void __devinit pcibios_fixup_bus(struct pci_bus *bus)
249{
250 /* Propagate hose info into the subordinate devices. */
251
252 struct pci_controller *hose = bus->sysdata;
253 struct list_head *ln;
254 struct pci_dev *dev = bus->self;
255
256 if (!dev) {
257 bus->resource[0] = hose->io_resource;
258 bus->resource[1] = hose->mem_resource;
259 } else if (pci_probe_only &&
260 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
261 pci_read_bridge_bases(bus);
262 pcibios_fixup_device_resources(dev, bus);
263 }
264
265 for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
266 struct pci_dev *dev = pci_dev_b(ln);
267
268 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
269 pcibios_fixup_device_resources(dev, bus);
270 }
271}
272
273void __init
274pcibios_update_irq(struct pci_dev *dev, int irq)
275{
276 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
277}
278
279void __devinit
280pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
281 struct resource *res)
282{
283 struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
284 unsigned long offset = 0;
285
286 if (res->flags & IORESOURCE_IO)
287 offset = hose->io_offset;
288 else if (res->flags & IORESOURCE_MEM)
289 offset = hose->mem_offset;
290
291 region->start = res->start - offset;
292 region->end = res->end - offset;
293}
294
295#ifdef CONFIG_HOTPLUG
296EXPORT_SYMBOL(pcibios_resource_to_bus);
297EXPORT_SYMBOL(PCIBIOS_MIN_IO);
298EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
299#endif
300
301char *pcibios_setup(char *str)
302{
303 return str;
304}