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; |
