diff options
Diffstat (limited to 'arch/mips/pci')
-rw-r--r-- | arch/mips/pci/Makefile | 7 | ||||
-rw-r--r-- | arch/mips/pci/fixup-ddb5074.c | 21 | ||||
-rw-r--r-- | arch/mips/pci/fixup-emma2rh.c | 102 | ||||
-rw-r--r-- | arch/mips/pci/fixup-excite.c | 36 | ||||
-rw-r--r-- | arch/mips/pci/fixup-wrppmc.c | 37 | ||||
-rw-r--r-- | arch/mips/pci/ops-bridge.c | 306 | ||||
-rw-r--r-- | arch/mips/pci/ops-ddb5074.c | 271 | ||||
-rw-r--r-- | arch/mips/pci/ops-ddb5476.c | 286 | ||||
-rw-r--r-- | arch/mips/pci/ops-emma2rh.c | 186 | ||||
-rw-r--r-- | arch/mips/pci/ops-it8172.c | 34 | ||||
-rw-r--r-- | arch/mips/pci/ops-sni.c | 12 | ||||
-rw-r--r-- | arch/mips/pci/ops-titan.c | 25 | ||||
-rw-r--r-- | arch/mips/pci/pci-ddb5074.c | 79 | ||||
-rw-r--r-- | arch/mips/pci/pci-ddb5476.c | 93 | ||||
-rw-r--r-- | arch/mips/pci/pci-ddb5477.c | 32 | ||||
-rw-r--r-- | arch/mips/pci/pci-emma2rh.c | 90 | ||||
-rw-r--r-- | arch/mips/pci/pci-excite.c | 149 | ||||
-rw-r--r-- | arch/mips/pci/pci-ip27.c | 295 | ||||
-rw-r--r-- | arch/mips/pci/pci-jmr3927.c | 16 | ||||
-rw-r--r-- | arch/mips/pci/pci-ocelot.c | 8 | ||||
-rw-r--r-- | arch/mips/pci/pci-yosemite.c | 10 | ||||
-rw-r--r-- | arch/mips/pci/pci.c | 5 |
22 files changed, 988 insertions, 1112 deletions
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 16205b587338..465778c5d816 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -18,12 +18,12 @@ obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o | |||
18 | obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o | 18 | obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o |
19 | obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o | 19 | obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o |
20 | obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o | 20 | obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o |
21 | obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o | ||
21 | 22 | ||
22 | # | 23 | # |
23 | # These are still pretty much in the old state, watch, go blind. | 24 | # These are still pretty much in the old state, watch, go blind. |
24 | # | 25 | # |
25 | obj-$(CONFIG_DDB5074) += fixup-ddb5074.o pci-ddb5074.o ops-ddb5074.o | 26 | obj-$(CONFIG_BASLER_EXCITE) = ops-titan.o pci-excite.o fixup-excite.o |
26 | obj-$(CONFIG_DDB5476) += ops-ddb5476.o pci-ddb5476.o | ||
27 | obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o | 27 | obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o |
28 | obj-$(CONFIG_LASAT) += pci-lasat.o | 28 | obj-$(CONFIG_LASAT) += pci-lasat.o |
29 | obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o | 29 | obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o |
@@ -43,7 +43,7 @@ obj-$(CONFIG_MOMENCO_OCELOT_C) += fixup-ocelot-c.o pci-ocelot-c.o | |||
43 | obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o pci-ocelot-g.o | 43 | obj-$(CONFIG_MOMENCO_OCELOT_G) += fixup-ocelot-g.o pci-ocelot-g.o |
44 | obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ | 44 | obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ |
45 | pci-yosemite.o | 45 | pci-yosemite.o |
46 | obj-$(CONFIG_SGI_IP27) += pci-ip27.o | 46 | obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o |
47 | obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o | 47 | obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o |
48 | obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o | 48 | obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o |
49 | obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o | 49 | obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o |
@@ -57,3 +57,4 @@ obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o | |||
57 | obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o | 57 | obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-tx4938.o ops-tx4938.o |
58 | obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o | 58 | obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o |
59 | obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o | 59 | obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o |
60 | obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o | ||
diff --git a/arch/mips/pci/fixup-ddb5074.c b/arch/mips/pci/fixup-ddb5074.c deleted file mode 100644 index 5a4a7c239c42..000000000000 --- a/arch/mips/pci/fixup-ddb5074.c +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * It's nice to have the LEDs on the GPIO pins available for debugging | ||
3 | */ | ||
4 | static 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 | |||
20 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, | ||
21 | ddb5074_fixup); | ||
diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c new file mode 100644 index 000000000000..3a34cd0efd6b --- /dev/null +++ b/arch/mips/pci/fixup-emma2rh.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * arch/mips/pci/fixup-emma2rh.c | ||
3 | * This file defines the PCI configration. | ||
4 | * | ||
5 | * Copyright (C) NEC Electronics Corporation 2004-2006 | ||
6 | * | ||
7 | * This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c | ||
8 | * | ||
9 | * Copyright 2001 MontaVista Software Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/pci.h> | ||
31 | |||
32 | #include <asm/bootinfo.h> | ||
33 | #include <asm/debug.h> | ||
34 | |||
35 | #include <asm/emma2rh/emma2rh.h> | ||
36 | |||
37 | #define EMMA2RH_PCI_HOST_SLOT 0x09 | ||
38 | #define EMMA2RH_USB_SLOT 0x03 | ||
39 | #define PCI_DEVICE_ID_NEC_EMMA2RH 0x014b /* EMMA2RH PCI Host */ | ||
40 | |||
41 | /* | ||
42 | * we fix up irqs based on the slot number. | ||
43 | * The first entry is at AD:11. | ||
44 | * Fortunately this works because, although we have two pci buses, | ||
45 | * they all have different slot numbers (except for rockhopper slot 20 | ||
46 | * which is handled below). | ||
47 | * | ||
48 | */ | ||
49 | |||
50 | #define MAX_SLOT_NUM 10 | ||
51 | static unsigned char irq_map[][5] __initdata = { | ||
52 | [3] = {0, MARKEINS_PCI_IRQ_INTB, MARKEINS_PCI_IRQ_INTC, | ||
53 | MARKEINS_PCI_IRQ_INTD, 0,}, | ||
54 | [4] = {0, MARKEINS_PCI_IRQ_INTA, 0, 0, 0,}, | ||
55 | [5] = {0, 0, 0, 0, 0,}, | ||
56 | [6] = {0, MARKEINS_PCI_IRQ_INTC, MARKEINS_PCI_IRQ_INTD, | ||
57 | MARKEINS_PCI_IRQ_INTA, MARKEINS_PCI_IRQ_INTB,}, | ||
58 | }; | ||
59 | |||
60 | static void __devinit nec_usb_controller_fixup(struct pci_dev *dev) | ||
61 | { | ||
62 | if (PCI_SLOT(dev->devfn) == EMMA2RH_USB_SLOT) | ||
63 | /* on board USB controller configuration */ | ||
64 | pci_write_config_dword(dev, 0xe4, 1 << 5); | ||
65 | } | ||
66 | |||
67 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB, | ||
68 | nec_usb_controller_fixup); | ||
69 | |||
70 | /* | ||
71 | * Prevent the PCI layer from seeing the resources allocated to this device | ||
72 | * if it is the host bridge by marking it as such. These resources are of | ||
73 | * no consequence to the PCI layer (they are handled elsewhere). | ||
74 | */ | ||
75 | static void __devinit emma2rh_pci_host_fixup(struct pci_dev *dev) | ||
76 | { | ||
77 | int i; | ||
78 | |||
79 | if (PCI_SLOT(dev->devfn) == EMMA2RH_PCI_HOST_SLOT) { | ||
80 | dev->class &= 0xff; | ||
81 | dev->class |= PCI_CLASS_BRIDGE_HOST << 8; | ||
82 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
83 | dev->resource[i].start = 0; | ||
84 | dev->resource[i].end = 0; | ||
85 | dev->resource[i].flags = 0; | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
90 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH, | ||
91 | emma2rh_pci_host_fixup); | ||
92 | |||
93 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
94 | { | ||
95 | return irq_map[slot][pin]; | ||
96 | } | ||
97 | |||
98 | /* Do platform specific device initialization at pci_enable_device() time */ | ||
99 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
100 | { | ||
101 | return 0; | ||
102 | } | ||
diff --git a/arch/mips/pci/fixup-excite.c b/arch/mips/pci/fixup-excite.c new file mode 100644 index 000000000000..1da696d43f00 --- /dev/null +++ b/arch/mips/pci/fixup-excite.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 by Basler Vision Technologies AG | ||
3 | * Author: Thomas Koeller <thomas.koeller@baslerweb.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (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 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <excite.h> | ||
23 | |||
24 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
25 | { | ||
26 | if (pin == 0) | ||
27 | return -1; | ||
28 | |||
29 | return USB_IRQ; /* USB controller is the only PCI device */ | ||
30 | } | ||
31 | |||
32 | /* Do platform specific device initialization at pci_enable_device() time */ | ||
33 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
34 | { | ||
35 | return 0; | ||
36 | } | ||
diff --git a/arch/mips/pci/fixup-wrppmc.c b/arch/mips/pci/fixup-wrppmc.c new file mode 100644 index 000000000000..3357c1300bb1 --- /dev/null +++ b/arch/mips/pci/fixup-wrppmc.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * fixup-wrppmc.c: PPMC board specific PCI fixup | ||
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) 2006, Wind River Inc. Rongkai.zhan (rongkai.zhan@windriver.com) | ||
9 | */ | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/pci.h> | ||
12 | #include <asm/gt64120.h> | ||
13 | |||
14 | /* PCI interrupt pins */ | ||
15 | #define PCI_INTA 1 | ||
16 | #define PCI_INTB 2 | ||
17 | #define PCI_INTC 3 | ||
18 | #define PCI_INTD 4 | ||
19 | |||
20 | #define PCI_SLOT_MAXNR 32 /* Each PCI bus has 32 physical slots */ | ||
21 | |||
22 | static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = { | ||
23 | /* 0 INTA INTB INTC INTD */ | ||
24 | [0] = {0, 0, 0, 0, 0}, /* Slot 0: GT64120 PCI bridge */ | ||
25 | [6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0}, | ||
26 | }; | ||
27 | |||
28 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
29 | { | ||
30 | return pci_irq_tab[slot][pin]; | ||
31 | } | ||
32 | |||
33 | /* Do platform specific device initialization at pci_enable_device() time */ | ||
34 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
35 | { | ||
36 | return 0; | ||
37 | } | ||
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c new file mode 100644 index 000000000000..1fa09929cd7a --- /dev/null +++ b/arch/mips/pci/ops-bridge.c | |||
@@ -0,0 +1,306 @@ | |||
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) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org) | ||
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | ||
8 | */ | ||
9 | #include <linux/pci.h> | ||
10 | #include <asm/paccess.h> | ||
11 | #include <asm/pci/bridge.h> | ||
12 | #include <asm/sn/arch.h> | ||
13 | #include <asm/sn/intr.h> | ||
14 | #include <asm/sn/sn0/hub.h> | ||
15 | |||
16 | /* | ||
17 | * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is | ||
18 | * not really documented, so right now I can't write code which uses it. | ||
19 | * Therefore we use type 0 accesses for now even though they won't work | ||
20 | * correcly for PCI-to-PCI bridges. | ||
21 | * | ||
22 | * The function is complicated by the ultimate brokeness of the IOC3 chip | ||
23 | * which is used in SGI systems. The IOC3 can only handle 32-bit PCI | ||
24 | * accesses and does only decode parts of it's address space. | ||
25 | */ | ||
26 | |||
27 | static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, | ||
28 | int where, int size, u32 * value) | ||
29 | { | ||
30 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | ||
31 | bridge_t *bridge = bc->base; | ||
32 | int slot = PCI_SLOT(devfn); | ||
33 | int fn = PCI_FUNC(devfn); | ||
34 | volatile void *addr; | ||
35 | u32 cf, shift, mask; | ||
36 | int res; | ||
37 | |||
38 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; | ||
39 | if (get_dbe(cf, (u32 *) addr)) | ||
40 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
41 | |||
42 | /* | ||
43 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
44 | * generic PCI code a chance to look at it for real ... | ||
45 | */ | ||
46 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | ||
47 | goto oh_my_gawd; | ||
48 | |||
49 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; | ||
50 | |||
51 | if (size == 1) | ||
52 | res = get_dbe(*value, (u8 *) addr); | ||
53 | else if (size == 2) | ||
54 | res = get_dbe(*value, (u16 *) addr); | ||
55 | else | ||
56 | res = get_dbe(*value, (u32 *) addr); | ||
57 | |||
58 | return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | ||
59 | |||
60 | oh_my_gawd: | ||
61 | |||
62 | /* | ||
63 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
64 | * generic PCI code a chance to look at the wrong register. | ||
65 | */ | ||
66 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { | ||
67 | *value = 0; | ||
68 | return PCIBIOS_SUCCESSFUL; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * IOC3 is fucked fucked beyond believe ... Don't try to access | ||
73 | * anything but 32-bit words ... | ||
74 | */ | ||
75 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; | ||
76 | |||
77 | if (get_dbe(cf, (u32 *) addr)) | ||
78 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
79 | |||
80 | shift = ((where & 3) << 3); | ||
81 | mask = (0xffffffffU >> ((4 - size) << 3)); | ||
82 | *value = (cf >> shift) & mask; | ||
83 | |||
84 | return PCIBIOS_SUCCESSFUL; | ||
85 | } | ||
86 | |||
87 | static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, | ||
88 | int where, int size, u32 * value) | ||
89 | { | ||
90 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | ||
91 | bridge_t *bridge = bc->base; | ||
92 | int busno = bus->number; | ||
93 | int slot = PCI_SLOT(devfn); | ||
94 | int fn = PCI_FUNC(devfn); | ||
95 | volatile void *addr; | ||
96 | u32 cf, shift, mask; | ||
97 | int res; | ||
98 | |||
99 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | ||
100 | addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; | ||
101 | if (get_dbe(cf, (u32 *) addr)) | ||
102 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
103 | |||
104 | /* | ||
105 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
106 | * generic PCI code a chance to look at it for real ... | ||
107 | */ | ||
108 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | ||
109 | goto oh_my_gawd; | ||
110 | |||
111 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | ||
112 | addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; | ||
113 | |||
114 | if (size == 1) | ||
115 | res = get_dbe(*value, (u8 *) addr); | ||
116 | else if (size == 2) | ||
117 | res = get_dbe(*value, (u16 *) addr); | ||
118 | else | ||
119 | res = get_dbe(*value, (u32 *) addr); | ||
120 | |||
121 | return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | ||
122 | |||
123 | oh_my_gawd: | ||
124 | |||
125 | /* | ||
126 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
127 | * generic PCI code a chance to look at the wrong register. | ||
128 | */ | ||
129 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { | ||
130 | *value = 0; | ||
131 | return PCIBIOS_SUCCESSFUL; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * IOC3 is fucked fucked beyond believe ... Don't try to access | ||
136 | * anything but 32-bit words ... | ||
137 | */ | ||
138 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | ||
139 | addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; | ||
140 | |||
141 | if (get_dbe(cf, (u32 *) addr)) | ||
142 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
143 | |||
144 | shift = ((where & 3) << 3); | ||
145 | mask = (0xffffffffU >> ((4 - size) << 3)); | ||
146 | *value = (cf >> shift) & mask; | ||
147 | |||
148 | return PCIBIOS_SUCCESSFUL; | ||
149 | } | ||
150 | |||
151 | static int pci_read_config(struct pci_bus *bus, unsigned int devfn, | ||
152 | int where, int size, u32 * value) | ||
153 | { | ||
154 | if (bus->number > 0) | ||
155 | return pci_conf1_read_config(bus, devfn, where, size, value); | ||
156 | |||
157 | return pci_conf0_read_config(bus, devfn, where, size, value); | ||
158 | } | ||
159 | |||
160 | static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, | ||
161 | int where, int size, u32 value) | ||
162 | { | ||
163 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | ||
164 | bridge_t *bridge = bc->base; | ||
165 | int slot = PCI_SLOT(devfn); | ||
166 | int fn = PCI_FUNC(devfn); | ||
167 | volatile void *addr; | ||
168 | u32 cf, shift, mask, smask; | ||
169 | int res; | ||
170 | |||
171 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; | ||
172 | if (get_dbe(cf, (u32 *) addr)) | ||
173 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
174 | |||
175 | /* | ||
176 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
177 | * generic PCI code a chance to look at it for real ... | ||
178 | */ | ||
179 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | ||
180 | goto oh_my_gawd; | ||
181 | |||
182 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; | ||
183 | |||
184 | if (size == 1) { | ||
185 | res = put_dbe(value, (u8 *) addr); | ||
186 | } else if (size == 2) { | ||
187 | res = put_dbe(value, (u16 *) addr); | ||
188 | } else { | ||
189 | res = put_dbe(value, (u32 *) addr); | ||
190 | } | ||
191 | |||
192 | if (res) | ||
193 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
194 | |||
195 | return PCIBIOS_SUCCESSFUL; | ||
196 | |||
197 | oh_my_gawd: | ||
198 | |||
199 | /* | ||
200 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
201 | * generic PCI code a chance to touch the wrong register. | ||
202 | */ | ||
203 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) | ||
204 | return PCIBIOS_SUCCESSFUL; | ||
205 | |||
206 | /* | ||
207 | * IOC3 is fucked fucked beyond believe ... Don't try to access | ||
208 | * anything but 32-bit words ... | ||
209 | */ | ||
210 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; | ||
211 | |||
212 | if (get_dbe(cf, (u32 *) addr)) | ||
213 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
214 | |||
215 | shift = ((where & 3) << 3); | ||
216 | mask = (0xffffffffU >> ((4 - size) << 3)); | ||
217 | smask = mask << shift; | ||
218 | |||
219 | cf = (cf & ~smask) | ((value & mask) << shift); | ||
220 | if (put_dbe(cf, (u32 *) addr)) | ||
221 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
222 | |||
223 | return PCIBIOS_SUCCESSFUL; | ||
224 | } | ||
225 | |||
226 | static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, | ||
227 | int where, int size, u32 value) | ||
228 | { | ||
229 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | ||
230 | bridge_t *bridge = bc->base; | ||
231 | int slot = PCI_SLOT(devfn); | ||
232 | int fn = PCI_FUNC(devfn); | ||
233 | int busno = bus->number; | ||
234 | volatile void *addr; | ||
235 | u32 cf, shift, mask, smask; | ||
236 | int res; | ||
237 | |||
238 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | ||
239 | addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; | ||
240 | if (get_dbe(cf, (u32 *) addr)) | ||
241 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
242 | |||
243 | /* | ||
244 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
245 | * generic PCI code a chance to look at it for real ... | ||
246 | */ | ||
247 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | ||
248 | goto oh_my_gawd; | ||
249 | |||
250 | addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; | ||
251 | |||
252 | if (size == 1) { | ||
253 | res = put_dbe(value, (u8 *) addr); | ||
254 | } else if (size == 2) { | ||
255 | res = put_dbe(value, (u16 *) addr); | ||
256 | } else { | ||
257 | res = put_dbe(value, (u32 *) addr); | ||
258 | } | ||
259 | |||
260 | if (res) | ||
261 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
262 | |||
263 | return PCIBIOS_SUCCESSFUL; | ||
264 | |||
265 | oh_my_gawd: | ||
266 | |||
267 | /* | ||
268 | * IOC3 is fucked fucked beyond believe ... Don't even give the | ||
269 | * generic PCI code a chance to touch the wrong register. | ||
270 | */ | ||
271 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) | ||
272 | return PCIBIOS_SUCCESSFUL; | ||
273 | |||
274 | /* | ||
275 | * IOC3 is fucked fucked beyond believe ... Don't try to access | ||
276 | * anything but 32-bit words ... | ||
277 | */ | ||
278 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; | ||
279 | |||
280 | if (get_dbe(cf, (u32 *) addr)) | ||
281 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
282 | |||
283 | shift = ((where & 3) << 3); | ||
284 | mask = (0xffffffffU >> ((4 - size) << 3)); | ||
285 | smask = mask << shift; | ||
286 | |||
287 | cf = (cf & ~smask) | ((value & mask) << shift); | ||
288 | if (put_dbe(cf, (u32 *) addr)) | ||
289 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
290 | |||
291 | return PCIBIOS_SUCCESSFUL; | ||
292 | } | ||
293 | |||
294 | static int pci_write_config(struct pci_bus *bus, unsigned int devfn, | ||
295 | int where, int size, u32 value) | ||
296 | { | ||
297 | if (bus->number > 0) | ||
298 | return pci_conf1_write_config(bus, devfn, where, size, value); | ||
299 | |||
300 | return pci_conf0_write_config(bus, devfn, where, size, value); | ||
301 | } | ||
302 | |||
303 | struct pci_ops bridge_pci_ops = { | ||
304 | .read = pci_read_config, | ||
305 | .write = pci_write_config, | ||
306 | }; | ||
diff --git a/arch/mips/pci/ops-ddb5074.c b/arch/mips/pci/ops-ddb5074.c deleted file mode 100644 index 89f97bef4fc4..000000000000 --- a/arch/mips/pci/ops-ddb5074.c +++ /dev/null | |||
@@ -1,271 +0,0 @@ | |||
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 | */ | ||
31 | struct 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 | */ | ||
43 | struct pci_config_swap ext_pci_swap = { | ||
44 | DDB_PCIW0, | ||
45 | DDB_PCIINIT0, | ||
46 | DDB_PCI_CONFIG_BASE, | ||
47 | DDB_PCI_CONFIG_SIZE | ||
48 | }; | ||
49 | |||
50 | static int pci_config_workaround = 1; | ||
51 | |||
52 | /* | ||
53 | * access config space | ||
54 | */ | ||
55 | static 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 | |||
123 | static 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 | |||
129 | static 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 | |||
154 | static 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 | |||
169 | static 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 | |||
184 | static 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 | |||
209 | static 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 | |||
228 | static 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) \ | ||
248 | static 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 | |||
256 | MAKE_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 | |||
264 | struct 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 deleted file mode 100644 index 12da58e75ec7..000000000000 --- a/arch/mips/pci/ops-ddb5476.c +++ /dev/null | |||
@@ -1,286 +0,0 @@ | |||
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 | */ | ||
31 | struct 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 | */ | ||
43 | struct pci_config_swap ext_pci_swap = { | ||
44 | DDB_PCIW0, | ||
45 | DDB_PCIINIT0, | ||
46 | DDB_PCI_CONFIG_BASE, | ||
47 | DDB_PCI_CONFIG_SIZE | ||
48 | }; | ||
49 | |||
50 | static int pci_config_workaround = 1; | ||
51 | |||
52 | /* | ||
53 | * access config space | ||
54 | */ | ||
55 | static 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 | |||
138 | static 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 | |||
144 | static 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 | |||
169 | static 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 | |||
184 | static 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 | |||
199 | static 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 | |||
224 | static 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 | |||
243 | static 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) \ | ||
263 | static 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 | |||
271 | MAKE_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 | |||
279 | struct 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-emma2rh.c b/arch/mips/pci/ops-emma2rh.c new file mode 100644 index 000000000000..e21b11bf66bc --- /dev/null +++ b/arch/mips/pci/ops-emma2rh.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* | ||
2 | * arch/mips/pci/ops-emma2rh.c | ||
3 | * This file defines the PCI operation for EMMA2RH. | ||
4 | * | ||
5 | * Copyright (C) NEC Electronics Corporation 2004-2006 | ||
6 | * | ||
7 | * This file is based on the arch/mips/pci/ops-vr41xx.c | ||
8 | * | ||
9 | * Copyright 2001 MontaVista Software Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/pci.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/types.h> | ||
30 | |||
31 | #include <asm/addrspace.h> | ||
32 | #include <asm/debug.h> | ||
33 | |||
34 | #include <asm/emma2rh/emma2rh.h> | ||
35 | |||
36 | #define RTABORT (0x1<<9) | ||
37 | #define RMABORT (0x1<<10) | ||
38 | #define EMMA2RH_PCI_SLOT_NUM 9 /* 0000:09.0 is final PCI device */ | ||
39 | |||
40 | /* | ||
41 | * access config space | ||
42 | */ | ||
43 | |||
44 | static int check_args(struct pci_bus *bus, u32 devfn, u32 * bus_num) | ||
45 | { | ||
46 | /* check if the bus is top-level */ | ||
47 | if (bus->parent != NULL) { | ||
48 | *bus_num = bus->number; | ||
49 | db_assert(bus_num != 0); | ||
50 | } else | ||
51 | *bus_num = 0; | ||
52 | |||
53 | if (*bus_num == 0) { | ||
54 | /* Type 0 */ | ||
55 | if (PCI_SLOT(devfn) >= 10) | ||
56 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
57 | } else { | ||
58 | /* Type 1 */ | ||
59 | if ((*bus_num >= 64) || (PCI_SLOT(devfn) >= 16)) | ||
60 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
61 | } | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static inline int set_pci_configuration_address(unsigned char bus_num, | ||
66 | unsigned int devfn, int where) | ||
67 | { | ||
68 | u32 config_win0; | ||
69 | |||
70 | emma2rh_out32(EMMA2RH_PCI_INT, ~RMABORT); | ||
71 | if (bus_num == 0) | ||
72 | /* | ||
73 | * Type 0 configuration | ||
74 | */ | ||
75 | config_win0 = (1 << (22 + PCI_SLOT(devfn))) | (5 << 9); | ||
76 | else | ||
77 | /* | ||
78 | * Type 1 configuration | ||
79 | */ | ||
80 | config_win0 = (bus_num << 26) | (PCI_SLOT(devfn) << 22) | | ||
81 | (1 << 15) | (5 << 9); | ||
82 | |||
83 | emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, config_win0); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where, | ||
89 | int size, uint32_t * val) | ||
90 | { | ||
91 | u32 bus_num; | ||
92 | u32 base = KSEG1ADDR(EMMA2RH_PCI_CONFIG_BASE); | ||
93 | u32 backup_win0; | ||
94 | u32 data; | ||
95 | |||
96 | *val = 0xffffffffU; | ||
97 | |||
98 | if (check_args(bus, devfn, &bus_num) == PCIBIOS_DEVICE_NOT_FOUND) | ||
99 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
100 | |||
101 | backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR); | ||
102 | |||
103 | if (set_pci_configuration_address(bus_num, devfn, where) < 0) | ||
104 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
105 | |||
106 | data = | ||
107 | *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) + | ||
108 | (where & 0xfffffffc)); | ||
109 | |||
110 | switch (size) { | ||
111 | case 1: | ||
112 | *val = (data >> ((where & 3) << 3)) & 0xffU; | ||
113 | break; | ||
114 | case 2: | ||
115 | *val = (data >> ((where & 2) << 3)) & 0xffffU; | ||
116 | break; | ||
117 | case 4: | ||
118 | *val = data; | ||
119 | break; | ||
120 | default: | ||
121 | emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0); | ||
122 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
123 | } | ||
124 | |||
125 | emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0); | ||
126 | |||
127 | if (emma2rh_in32(EMMA2RH_PCI_INT) & RMABORT) | ||
128 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
129 | |||
130 | return PCIBIOS_SUCCESSFUL; | ||
131 | } | ||
132 | |||
133 | static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where, | ||
134 | int size, u32 val) | ||
135 | { | ||
136 | u32 bus_num; | ||
137 | u32 base = KSEG1ADDR(EMMA2RH_PCI_CONFIG_BASE); | ||
138 | u32 backup_win0; | ||
139 | u32 data; | ||
140 | int shift; | ||
141 | |||
142 | if (check_args(bus, devfn, &bus_num) == PCIBIOS_DEVICE_NOT_FOUND) | ||
143 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
144 | |||
145 | backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR); | ||
146 | |||
147 | if (set_pci_configuration_address(bus_num, devfn, where) < 0) | ||
148 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
149 | |||
150 | /* read modify write */ | ||
151 | data = | ||
152 | *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) + | ||
153 | (where & 0xfffffffc)); | ||
154 | |||
155 | switch (size) { | ||
156 | case 1: | ||
157 | shift = (where & 3) << 3; | ||
158 | data &= ~(0xffU << shift); | ||
159 | data |= ((val & 0xffU) << shift); | ||
160 | break; | ||
161 | case 2: | ||
162 | shift = (where & 2) << 3; | ||
163 | data &= ~(0xffffU << shift); | ||
164 | data |= ((val & 0xffffU) << shift); | ||
165 | break; | ||
166 | case 4: | ||
167 | data = val; | ||
168 | break; | ||
169 | default: | ||
170 | emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0); | ||
171 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
172 | } | ||
173 | *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) + | ||
174 | (where & 0xfffffffc)) = data; | ||
175 | |||
176 | emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0); | ||
177 | if (emma2rh_in32(EMMA2RH_PCI_INT) & RMABORT) | ||
178 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
179 | |||
180 | return PCIBIOS_SUCCESSFUL; | ||
181 | } | ||
182 | |||
183 | struct pci_ops emma2rh_pci_ops = { | ||
184 | .read = pci_config_read, | ||
185 | .write = pci_config_write, | ||
186 | }; | ||
diff --git a/arch/mips/pci/ops-it8172.c b/arch/mips/pci/ops-it8172.c index b7a8b9a6f9db..ba8328505a0a 100644 --- a/arch/mips/pci/ops-it8172.c +++ b/arch/mips/pci/ops-it8172.c | |||
@@ -50,30 +50,28 @@ | |||
50 | static struct resource pci_mem_resource_1; | 50 | static struct resource pci_mem_resource_1; |
51 | 51 | ||
52 | static struct resource pci_io_resource = { | 52 | static struct resource pci_io_resource = { |
53 | "io pci IO space", | 53 | .start = 0x14018000, |
54 | 0x14018000, | 54 | .end = 0x17FFFFFF, |
55 | 0x17FFFFFF, | 55 | .name = "io pci IO space", |
56 | IORESOURCE_IO | 56 | .flags = IORESOURCE_IO |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static struct resource pci_mem_resource_0 = { | 59 | static struct resource pci_mem_resource_0 = { |
60 | "ext pci memory space 0/1", | 60 | .start = 0x10101000, |
61 | 0x10101000, | 61 | .end = 0x13FFFFFF, |
62 | 0x13FFFFFF, | 62 | .name = "ext pci memory space 0/1", |
63 | IORESOURCE_MEM, | 63 | .flags = IORESOURCE_MEM, |
64 | &pci_mem_resource_0, | 64 | .parent = &pci_mem_resource_0, |
65 | NULL, | 65 | .sibling = NULL, |
66 | &pci_mem_resource_1 | 66 | .child = &pci_mem_resource_1 |
67 | }; | 67 | }; |
68 | 68 | ||
69 | static struct resource pci_mem_resource_1 = { | 69 | static struct resource pci_mem_resource_1 = { |
70 | "ext pci memory space 2/3", | 70 | .start = 0x1A000000, |
71 | 0x1A000000, | 71 | .end = 0x1FBFFFFF, |
72 | 0x1FBFFFFF, | 72 | .name = "ext pci memory space 2/3", |
73 | IORESOURCE_MEM, | 73 | .flags = IORESOURCE_MEM, |
74 | &pci_mem_resource_0, | 74 | .parent = &pci_mem_resource_0 |
75 | NULL, | ||
76 | NULL | ||
77 | }; | 75 | }; |
78 | 76 | ||
79 | extern struct pci_ops it8172_pci_ops; | 77 | extern struct pci_ops it8172_pci_ops; |
diff --git a/arch/mips/pci/ops-sni.c b/arch/mips/pci/ops-sni.c index 62bdd19c7f8e..2b0ccd6d9dcd 100644 --- a/arch/mips/pci/ops-sni.c +++ b/arch/mips/pci/ops-sni.c | |||
@@ -47,13 +47,13 @@ static int pcimt_read(struct pci_bus *bus, unsigned int devfn, int reg, | |||
47 | 47 | ||
48 | switch (size) { | 48 | switch (size) { |
49 | case 1: | 49 | case 1: |
50 | *val = *(volatile u8 *) (PCIMT_CONFIG_DATA + (reg & 3)); | 50 | *val = inb(PCIMT_CONFIG_DATA + (reg & 3)); |
51 | break; | 51 | break; |
52 | case 2: | 52 | case 2: |
53 | *val = *(volatile u16 *) (PCIMT_CONFIG_DATA + (reg & 2)); | 53 | *val = inw(PCIMT_CONFIG_DATA + (reg & 2)); |
54 | break; | 54 | break; |
55 | case 4: | 55 | case 4: |
56 | *val = *(volatile u32 *) PCIMT_CONFIG_DATA; | 56 | *val = inl(PCIMT_CONFIG_DATA); |
57 | break; | 57 | break; |
58 | } | 58 | } |
59 | 59 | ||
@@ -70,13 +70,13 @@ static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg, | |||
70 | 70 | ||
71 | switch (size) { | 71 | switch (size) { |
72 | case 1: | 72 | case 1: |
73 | *(volatile u8 *) (PCIMT_CONFIG_DATA + (reg & 3)) = val; | 73 | outb (val, PCIMT_CONFIG_DATA + (reg & 3)); |
74 | break; | 74 | break; |
75 | case 2: | 75 | case 2: |
76 | *(volatile u16 *) (PCIMT_CONFIG_DATA + (reg & 2)) = val; | 76 | outw (val, PCIMT_CONFIG_DATA + (reg & 2)); |
77 | break; | 77 | break; |
78 | case 4: | 78 | case 4: |
79 | *(volatile u32 *) PCIMT_CONFIG_DATA = val; | 79 | outl (val, PCIMT_CONFIG_DATA); |
80 | break; | 80 | break; |
81 | } | 81 | } |
82 | 82 | ||
diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c index 233ec6f2054d..ebf8fc40e9b2 100644 --- a/arch/mips/pci/ops-titan.c +++ b/arch/mips/pci/ops-titan.c | |||
@@ -26,8 +26,19 @@ | |||
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | 28 | ||
29 | #include <asm/titan_dep.h> | 29 | #include <asm/pci.h> |
30 | #include <asm/io.h> | ||
31 | #include <asm/rm9k-ocd.h> | ||
30 | 32 | ||
33 | /* | ||
34 | * PCI specific defines | ||
35 | */ | ||
36 | #define TITAN_PCI_0_CONFIG_ADDRESS 0x780 | ||
37 | #define TITAN_PCI_0_CONFIG_DATA 0x784 | ||
38 | |||
39 | /* | ||
40 | * Titan PCI Config Read Byte | ||
41 | */ | ||
31 | static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, | 42 | static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, |
32 | int size, u32 * val) | 43 | int size, u32 * val) |
33 | { | 44 | { |
@@ -43,8 +54,8 @@ static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg, | |||
43 | 54 | ||
44 | 55 | ||
45 | /* start the configuration cycle */ | 56 | /* start the configuration cycle */ |
46 | TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address); | 57 | ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS); |
47 | tmp = TITAN_READ(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3); | 58 | tmp = ocd_readl(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3); |
48 | 59 | ||
49 | switch (size) { | 60 | switch (size) { |
50 | case 1: | 61 | case 1: |
@@ -71,20 +82,20 @@ static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg, | |||
71 | (reg & 0xfc) | 0x80000000; | 82 | (reg & 0xfc) | 0x80000000; |
72 | 83 | ||
73 | /* start the configuration cycle */ | 84 | /* start the configuration cycle */ |
74 | TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address); | 85 | ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS); |
75 | 86 | ||
76 | /* write the data */ | 87 | /* write the data */ |
77 | switch (size) { | 88 | switch (size) { |
78 | case 1: | 89 | case 1: |
79 | TITAN_WRITE_8(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3), val); | 90 | ocd_writeb(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3)); |
80 | break; | 91 | break; |
81 | 92 | ||
82 | case 2: | 93 | case 2: |
83 | TITAN_WRITE_16(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2), val); | 94 | ocd_writew(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2)); |
84 | break; | 95 | break; |
85 | 96 | ||
86 | case 4: | 97 | case 4: |
87 | TITAN_WRITE(TITAN_PCI_0_CONFIG_DATA, val); | 98 | ocd_writel(val, TITAN_PCI_0_CONFIG_DATA); |
88 | break; | 99 | break; |
89 | } | 100 | } |
90 | 101 | ||
diff --git a/arch/mips/pci/pci-ddb5074.c b/arch/mips/pci/pci-ddb5074.c deleted file mode 100644 index 73f9ceeb2f55..000000000000 --- a/arch/mips/pci/pci-ddb5074.c +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
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 | |||
10 | static 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 | |||
17 | static 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 | |||
24 | extern struct pci_ops ddb5476_ext_pci_ops; | ||
25 | |||
26 | struct 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 | |||
40 | static 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 | |||
51 | int __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 */ | ||
57 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
58 | { | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | void __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 deleted file mode 100644 index 90dd49509800..000000000000 --- a/arch/mips/pci/pci-ddb5476.c +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
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 | |||
10 | static 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 | |||
17 | static 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 | |||
24 | extern struct pci_ops ddb5476_ext_pci_ops; | ||
25 | |||
26 | struct 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 | ||
54 | static 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 | |||
65 | int __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 */ | ||
71 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
72 | { | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | void __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 index 826d653184e5..d071bc375b11 100644 --- a/arch/mips/pci/pci-ddb5477.c +++ b/arch/mips/pci/pci-ddb5477.c | |||
@@ -22,31 +22,31 @@ | |||
22 | #include <asm/ddb5xxx/ddb5xxx.h> | 22 | #include <asm/ddb5xxx/ddb5xxx.h> |
23 | 23 | ||
24 | static struct resource extpci_io_resource = { | 24 | static struct resource extpci_io_resource = { |
25 | "ext pci IO space", | 25 | .start = DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000, |
26 | DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000, | 26 | .end = DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE - 1, |
27 | DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE - 1, | 27 | .name = "ext pci IO space", |
28 | IORESOURCE_IO | 28 | .flags = IORESOURCE_IO |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static struct resource extpci_mem_resource = { | 31 | static struct resource extpci_mem_resource = { |
32 | "ext pci memory space", | 32 | .start = DDB_PCI0_MEM_BASE + 0x100000, |
33 | DDB_PCI0_MEM_BASE + 0x100000, | 33 | .end = DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE - 1, |
34 | DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE - 1, | 34 | .name = "ext pci memory space", |
35 | IORESOURCE_MEM | 35 | .flags = IORESOURCE_MEM |
36 | }; | 36 | }; |
37 | 37 | ||
38 | static struct resource iopci_io_resource = { | 38 | static struct resource iopci_io_resource = { |
39 | "io pci IO space", | 39 | .start = DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE, |
40 | DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE, | 40 | .end = DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE - 1, |
41 | DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE - 1, | 41 | .name = "io pci IO space", |
42 | IORESOURCE_IO | 42 | .flags = IORESOURCE_IO |
43 | }; | 43 | }; |
44 | 44 | ||
45 | static struct resource iopci_mem_resource = { | 45 | static struct resource iopci_mem_resource = { |
46 | "ext pci memory space", | 46 | .start = DDB_PCI1_MEM_BASE, |
47 | DDB_PCI1_MEM_BASE, | 47 | .end = DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE - 1, |
48 | DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE - 1, | 48 | .name = "ext pci memory space", |
49 | IORESOURCE_MEM | 49 | .flags = IORESOURCE_MEM |
50 | }; | 50 | }; |
51 | 51 | ||
52 | extern struct pci_ops ddb5477_ext_pci_ops; | 52 | extern struct pci_ops ddb5477_ext_pci_ops; |
diff --git a/arch/mips/pci/pci-emma2rh.c b/arch/mips/pci/pci-emma2rh.c new file mode 100644 index 000000000000..0f8b230057d3 --- /dev/null +++ b/arch/mips/pci/pci-emma2rh.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * arch/mips/pci/pci-emma2rh.c | ||
3 | * This file defines the PCI configration. | ||
4 | * | ||
5 | * Copyright (C) NEC Electronics Corporation 2004-2006 | ||
6 | * | ||
7 | * This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c | ||
8 | * | ||
9 | * Copyright 2001 MontaVista Software Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/pci.h> | ||
31 | |||
32 | #include <asm/bootinfo.h> | ||
33 | #include <asm/debug.h> | ||
34 | |||
35 | #include <asm/emma2rh/emma2rh.h> | ||
36 | |||
37 | static struct resource pci_io_resource = { | ||
38 | .name = "pci IO space", | ||
39 | .start = EMMA2RH_PCI_IO_BASE, | ||
40 | .end = EMMA2RH_PCI_IO_BASE + EMMA2RH_PCI_IO_SIZE - 1, | ||
41 | .flags = IORESOURCE_IO, | ||
42 | }; | ||
43 | |||
44 | static struct resource pci_mem_resource = { | ||
45 | .name = "pci memory space", | ||
46 | .start = EMMA2RH_PCI_MEM_BASE, | ||
47 | .end = EMMA2RH_PCI_MEM_BASE + EMMA2RH_PCI_MEM_SIZE - 1, | ||
48 | .flags = IORESOURCE_MEM, | ||
49 | }; | ||
50 | |||
51 | extern struct pci_ops emma2rh_pci_ops; | ||
52 | |||
53 | static struct pci_controller emma2rh_pci_controller = { | ||
54 | .pci_ops = &emma2rh_pci_ops, | ||
55 | .mem_resource = &pci_mem_resource, | ||
56 | .io_resource = &pci_io_resource, | ||
57 | .mem_offset = -0x04000000, | ||
58 | .io_offset = 0, | ||
59 | }; | ||
60 | |||
61 | static void __init emma2rh_pci_init(void) | ||
62 | { | ||
63 | /* setup PCI interface */ | ||
64 | emma2rh_out32(EMMA2RH_PCI_ARBIT_CTR, 0x70f); | ||
65 | |||
66 | emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, 0x80000a18); | ||
67 | emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_COMMAND, | ||
68 | PCI_STATUS_DEVSEL_MEDIUM | PCI_STATUS_CAP_LIST | | ||
69 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); | ||
70 | emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_BASE_ADDRESS_0, 0x10000000); | ||
71 | emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_BASE_ADDRESS_1, 0x00000000); | ||
72 | |||
73 | emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, 0x12000000 | 0x218); | ||
74 | emma2rh_out32(EMMA2RH_PCI_IWIN1_CTR, 0x18000000 | 0x600); | ||
75 | emma2rh_out32(EMMA2RH_PCI_INIT_ESWP, 0x00000200); | ||
76 | |||
77 | emma2rh_out32(EMMA2RH_PCI_TWIN_CTR, 0x00009200); | ||
78 | emma2rh_out32(EMMA2RH_PCI_TWIN_BADR, 0x00000000); | ||
79 | emma2rh_out32(EMMA2RH_PCI_TWIN0_DADR, 0x00000000); | ||
80 | emma2rh_out32(EMMA2RH_PCI_TWIN1_DADR, 0x00000000); | ||
81 | } | ||
82 | |||
83 | static int __init emma2rh_pci_setup(void) | ||
84 | { | ||
85 | emma2rh_pci_init(); | ||
86 | register_pci_controller(&emma2rh_pci_controller); | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | arch_initcall(emma2rh_pci_setup); | ||
diff --git a/arch/mips/pci/pci-excite.c b/arch/mips/pci/pci-excite.c new file mode 100644 index 000000000000..3c86c77cb74f --- /dev/null +++ b/arch/mips/pci/pci-excite.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 by Basler Vision Technologies AG | ||
3 | * Author: Thomas Koeller <thomas.koeller@baslerweb.com> | ||
4 | * Based on the PMC-Sierra Yosemite board support by Ralf Baechle. | ||
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/kernel.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/bitops.h> | ||
25 | #include <asm/rm9k-ocd.h> | ||
26 | #include <excite.h> | ||
27 | |||
28 | |||
29 | extern struct pci_ops titan_pci_ops; | ||
30 | |||
31 | |||
32 | static struct resource | ||
33 | mem_resource = { | ||
34 | .name = "PCI memory", | ||
35 | .start = EXCITE_PHYS_PCI_MEM, | ||
36 | .end = EXCITE_PHYS_PCI_MEM + EXCITE_SIZE_PCI_MEM - 1, | ||
37 | .flags = IORESOURCE_MEM | ||
38 | }, | ||
39 | io_resource = { | ||
40 | .name = "PCI I/O", | ||
41 | .start = EXCITE_PHYS_PCI_IO, | ||
42 | .end = EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1, | ||
43 | .flags = IORESOURCE_IO | ||
44 | }; | ||
45 | |||
46 | |||
47 | static struct pci_controller bx_controller = { | ||
48 | .pci_ops = &titan_pci_ops, | ||
49 | .mem_resource = &mem_resource, | ||
50 | .mem_offset = 0x00000000UL, | ||
51 | .io_resource = &io_resource, | ||
52 | .io_offset = 0x00000000UL | ||
53 | }; | ||
54 | |||
55 | |||
56 | static char | ||
57 | iopage_failed[] __initdata = "Cannot allocate PCI I/O page", | ||
58 | modebits_no_pci[] __initdata = "PCI is not configured in mode bits"; | ||
59 | |||
60 | #define RM9000x2_OCD_HTSC 0x0604 | ||
61 | #define RM9000x2_OCD_HTBHL 0x060c | ||
62 | #define RM9000x2_OCD_PCIHRST 0x078c | ||
63 | |||
64 | #define RM9K_OCD_MODEBIT1 0x00d4 /* (MODEBIT1) Mode Bit 1 */ | ||
65 | #define RM9K_OCD_CPHDCR 0x00f4 /* CPU-PCI/HT Data Control. */ | ||
66 | |||
67 | #define PCISC_FB2B 0x00000200 | ||
68 | #define PCISC_MWICG 0x00000010 | ||
69 | #define PCISC_EMC 0x00000004 | ||
70 | #define PCISC_ERMA 0x00000002 | ||
71 | |||
72 | |||
73 | |||
74 | static int __init basler_excite_pci_setup(void) | ||
75 | { | ||
76 | const unsigned int fullbars = memsize / (256 << 20); | ||
77 | unsigned int i; | ||
78 | |||
79 | /* Check modebits to see if PCI is really enabled. */ | ||
80 | if (!((ocd_readl(RM9K_OCD_MODEBIT1) >> (47-32)) & 0x1)) | ||
81 | panic(modebits_no_pci); | ||
82 | |||
83 | if (NULL == request_mem_region(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO, | ||
84 | "Memory-mapped PCI I/O page")) | ||
85 | panic(iopage_failed); | ||
86 | |||
87 | /* Enable PCI 0 as master for config cycles */ | ||
88 | ocd_writel(PCISC_EMC | PCISC_ERMA, RM9000x2_OCD_HTSC); | ||
89 | |||
90 | |||
91 | /* Set up latency timer */ | ||
92 | ocd_writel(0x8008, RM9000x2_OCD_HTBHL); | ||
93 | |||
94 | /* Setup host IO and Memory space */ | ||
95 | ocd_writel((EXCITE_PHYS_PCI_IO >> 4) | 1, LKB7); | ||
96 | ocd_writel(((EXCITE_SIZE_PCI_IO >> 4) & 0x7fffff00) - 0x100, LKM7); | ||
97 | ocd_writel((EXCITE_PHYS_PCI_MEM >> 4) | 1, LKB8); | ||
98 | ocd_writel(((EXCITE_SIZE_PCI_MEM >> 4) & 0x7fffff00) - 0x100, LKM8); | ||
99 | |||
100 | /* Set up PCI BARs to map all installed memory */ | ||
101 | for (i = 0; i < 6; i++) { | ||
102 | const unsigned int bar = 0x610 + i * 4; | ||
103 | |||
104 | if (i < fullbars) { | ||
105 | ocd_writel(0x10000000 * i, bar); | ||
106 | ocd_writel(0x01000000 * i, bar + 0x140); | ||
107 | ocd_writel(0x0ffff029, bar + 0x100); | ||
108 | continue; | ||
109 | } | ||
110 | |||
111 | if (i == fullbars) { | ||
112 | int o; | ||
113 | u32 mask; | ||
114 | |||
115 | const unsigned long rem = memsize - i * 0x10000000; | ||
116 | if (!rem) { | ||
117 | ocd_writel(0x00000000, bar + 0x100); | ||
118 | continue; | ||
119 | } | ||
120 | |||
121 | o = ffs(rem) - 1; | ||
122 | if (rem & ~(0x1 << o)) | ||
123 | o++; | ||
124 | mask = ((0x1 << o) & 0x0ffff000) - 0x1000; | ||
125 | ocd_writel(0x10000000 * i, bar); | ||
126 | ocd_writel(0x01000000 * i, bar + 0x140); | ||
127 | ocd_writel(0x00000029 | mask, bar + 0x100); | ||
128 | continue; | ||
129 | } | ||
130 | |||
131 | ocd_writel(0x00000000, bar + 0x100); | ||
132 | } | ||
133 | |||
134 | /* Finally, enable the PCI interupt */ | ||
135 | #if USB_IRQ > 7 | ||
136 | set_c0_intcontrol(1 << USB_IRQ); | ||
137 | #else | ||
138 | set_c0_status(1 << (USB_IRQ + 8)); | ||
139 | #endif | ||
140 | |||
141 | ioport_resource.start = EXCITE_PHYS_PCI_IO; | ||
142 | ioport_resource.end = EXCITE_PHYS_PCI_IO + EXCITE_SIZE_PCI_IO - 1; | ||
143 | set_io_port_base((unsigned long) ioremap_nocache(EXCITE_PHYS_PCI_IO, EXCITE_SIZE_PCI_IO)); | ||
144 | register_pci_controller(&bx_controller); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | |||
149 | arch_initcall(basler_excite_pci_setup); | ||
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 6002d2a6a262..80eb9af9ecdf 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c | |||
@@ -40,297 +40,7 @@ static struct bridge_controller bridges[MAX_PCI_BUSSES]; | |||
40 | struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; | 40 | struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; |
41 | int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; | 41 | int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; |
42 | 42 | ||
43 | /* | 43 | extern struct pci_ops bridge_pci_ops; |
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 | |||
54 | static 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 | |||
87 | oh_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 | |||
114 | static 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 | |||
150 | oh_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 | |||
178 | static 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 | |||
187 | static 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 | |||
224 | oh_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 | |||
253 | static 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 | |||
292 | oh_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 | |||
321 | static 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 | |||
330 | static struct pci_ops bridge_pci_ops = { | ||
331 | .read = pci_read_config, | ||
332 | .write = pci_write_config, | ||
333 | }; | ||
334 | 44 | ||
335 | int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid) | 45 | int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid) |
336 | { | 46 | { |
@@ -370,8 +80,7 @@ int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid) | |||
370 | bc->widget_id = widget_id; | 80 | bc->widget_id = widget_id; |
371 | bc->nasid = nasid; | 81 | bc->nasid = nasid; |
372 | 82 | ||
373 | bc->baddr = (u64)masterwid << 60; | 83 | bc->baddr = (u64)masterwid << 60 | PCI64_ATTR_BAR; |
374 | bc->baddr |= (1UL << 56); /* Barrier set */ | ||
375 | 84 | ||
376 | /* | 85 | /* |
377 | * point to this bridge | 86 | * point to this bridge |
diff --git a/arch/mips/pci/pci-jmr3927.c b/arch/mips/pci/pci-jmr3927.c index f02ef6e36b02..cb84f4e8ccae 100644 --- a/arch/mips/pci/pci-jmr3927.c +++ b/arch/mips/pci/pci-jmr3927.c | |||
@@ -35,17 +35,17 @@ | |||
35 | #include <asm/debug.h> | 35 | #include <asm/debug.h> |
36 | 36 | ||
37 | struct resource pci_io_resource = { | 37 | struct resource pci_io_resource = { |
38 | "IO MEM", | 38 | .name = "IO MEM", |
39 | 0x1000, /* reserve regacy I/O space */ | 39 | .start = 0x1000, /* reserve regacy I/O space */ |
40 | 0x1000 + JMR3927_PCIIO_SIZE - 1, | 40 | .end = 0x1000 + JMR3927_PCIIO_SIZE - 1, |
41 | IORESOURCE_IO | 41 | .flags = IORESOURCE_IO |
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct resource pci_mem_resource = { | 44 | struct resource pci_mem_resource = { |
45 | "PCI MEM", | 45 | .name = "PCI MEM", |
46 | JMR3927_PCIMEM, | 46 | .start = JMR3927_PCIMEM, |
47 | JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE - 1, | 47 | .end = JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE - 1, |
48 | IORESOURCE_MEM | 48 | .flags = IORESOURCE_MEM |
49 | }; | 49 | }; |
50 | 50 | ||
51 | extern struct pci_ops jmr3927_pci_ops; | 51 | extern struct pci_ops jmr3927_pci_ops; |
diff --git a/arch/mips/pci/pci-ocelot.c b/arch/mips/pci/pci-ocelot.c index 3da8a4ee6baa..2b9495dce6ba 100644 --- a/arch/mips/pci/pci-ocelot.c +++ b/arch/mips/pci/pci-ocelot.c | |||
@@ -71,13 +71,13 @@ static inline void pci0WriteConfigReg(unsigned int offset, unsigned int data) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | static struct resource ocelot_mem_resource = { | 73 | static struct resource ocelot_mem_resource = { |
74 | iomem_resource.start = GT_PCI_MEM_BASE; | 74 | start = GT_PCI_MEM_BASE; |
75 | iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1; | 75 | end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct resource ocelot_io_resource = { | 78 | static struct resource ocelot_io_resource = { |
79 | ioport_resource.start = GT_PCI_IO_BASE; | 79 | start = GT_PCI_IO_BASE; |
80 | ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; | 80 | end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static struct pci_controller ocelot_pci_controller = { | 83 | static struct pci_controller ocelot_pci_controller = { |
diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c index dac9ed4b0ccf..0357946f30e6 100644 --- a/arch/mips/pci/pci-yosemite.c +++ b/arch/mips/pci/pci-yosemite.c | |||
@@ -14,7 +14,10 @@ | |||
14 | extern struct pci_ops titan_pci_ops; | 14 | extern struct pci_ops titan_pci_ops; |
15 | 15 | ||
16 | static struct resource py_mem_resource = { | 16 | static struct resource py_mem_resource = { |
17 | "Titan PCI MEM", 0xe0000000UL, 0xe3ffffffUL, IORESOURCE_MEM | 17 | .start = 0xe0000000UL, |
18 | .end = 0xe3ffffffUL, | ||
19 | .name = "Titan PCI MEM", | ||
20 | .flags = IORESOURCE_MEM | ||
18 | }; | 21 | }; |
19 | 22 | ||
20 | /* | 23 | /* |
@@ -26,7 +29,10 @@ static struct resource py_mem_resource = { | |||
26 | #define TITAN_IO_BASE 0xe8000000UL | 29 | #define TITAN_IO_BASE 0xe8000000UL |
27 | 30 | ||
28 | static struct resource py_io_resource = { | 31 | static struct resource py_io_resource = { |
29 | "Titan IO MEM", 0x00001000UL, TITAN_IO_SIZE - 1, IORESOURCE_IO, | 32 | .start = 0x00001000UL, |
33 | .end = TITAN_IO_SIZE - 1, | ||
34 | .name = "Titan IO MEM", | ||
35 | .flags = IORESOURCE_IO, | ||
30 | }; | 36 | }; |
31 | 37 | ||
32 | static struct pci_controller py_controller = { | 38 | static struct pci_controller py_controller = { |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 21402ffd7c98..4dfce154d4af 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -76,11 +76,6 @@ pcibios_align_resource(void *data, struct resource *res, | |||
76 | res->start = start; | 76 | res->start = start; |
77 | } | 77 | } |
78 | 78 | ||
79 | struct pci_controller * __init alloc_pci_controller(void) | ||
80 | { | ||
81 | return alloc_bootmem(sizeof(struct pci_controller)); | ||
82 | } | ||
83 | |||
84 | void __init register_pci_controller(struct pci_controller *hose) | 79 | void __init register_pci_controller(struct pci_controller *hose) |
85 | { | 80 | { |
86 | *hose_tail = hose; | 81 | *hose_tail = hose; |