diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-07-10 17:33:08 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-07-15 19:44:35 +0200 |
commit | 89d63fe179520b11f54de1f26755b7444c79e73a (patch) | |
tree | fede06c5648335652c864fc35c951d991cbab183 /arch/mips/pci | |
parent | [MIPS] TXx9: Reorganize code (diff) | |
download | linux-89d63fe179520b11f54de1f26755b7444c79e73a.tar.xz linux-89d63fe179520b11f54de1f26755b7444c79e73a.zip |
[MIPS] TXx9: Reorganize PCI code
Split out PCIC dependent code and SoC dependent code from board dependent
code. Now TX4927 PCIC code is independent from TX4927/TX4938 SoC code.
Also fix some build problems on CONFIG_PCI=n.
As a bonus, "FPCIB0 Backplane Support" is available for all TX39/TX49 boards
and PCI66 support is available for all TX49 boards.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/pci')
-rw-r--r-- | arch/mips/pci/Makefile | 8 | ||||
-rw-r--r-- | arch/mips/pci/fixup-jmr3927.c | 25 | ||||
-rw-r--r-- | arch/mips/pci/fixup-rbtx4927.c | 112 | ||||
-rw-r--r-- | arch/mips/pci/fixup-rbtx4938.c | 52 | ||||
-rw-r--r-- | arch/mips/pci/ops-tx3927.c | 87 | ||||
-rw-r--r-- | arch/mips/pci/ops-tx4927.c | 514 | ||||
-rw-r--r-- | arch/mips/pci/ops-tx4938.c | 214 | ||||
-rw-r--r-- | arch/mips/pci/pci-jmr3927.c | 58 | ||||
-rw-r--r-- | arch/mips/pci/pci-tx4927.c | 83 | ||||
-rw-r--r-- | arch/mips/pci/pci-tx4938.c | 134 |
10 files changed, 706 insertions, 581 deletions
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 4608e43de28c..908764878ac8 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -15,6 +15,8 @@ obj-$(CONFIG_MIPS_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o obj-$(CONFIG_NEC_CMBVR4133) += fixup-vr4133.o obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o +obj-$(CONFIG_PCI_TX3927) += ops-tx3927.o +obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o # # These are still pretty much in the old state, watch, go blind. @@ -41,9 +43,9 @@ obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o -obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o pci-jmr3927.o -obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o ops-tx4927.o -obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o ops-tx4938.o +obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o +obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o pci-tx4927.o pci-tx4938.o +obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o pci-tx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index 41dcd6a3aae5..d5edaf21e088 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -28,36 +28,31 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/types.h> -#include <linux/pci.h> -#include <linux/init.h> - +#include <asm/txx9/pci.h> #include <asm/txx9/jmr3927.h> int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; - /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ - if (dev->vendor == PCI_VENDOR_ID_EFAR && - dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1) - return irq; /* IRQ rotation (PICMG) */ irq--; /* 0-3 */ - if (dev->bus->parent == NULL && - slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) { + if (slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) { /* PCI CardSlot (IDSEL=A23, DevNu=12) */ /* PCIA => PCIC (IDSEL=A23) */ /* NOTE: JMR3927 JP1 must be set to OPEN */ irq = (irq + 2) % 4; - } else if (dev->bus->parent == NULL && - slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) { + } else if (slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) { /* PCI CardSlot (IDSEL=A22, DevNu=11) */ /* PCIA => PCIA (IDSEL=A22) */ /* NOTE: JMR3927 JP1 must be set to OPEN */ irq = (irq + 0) % 4; } else { /* PCI Backplane */ - irq = (irq + 3 + slot) % 4; + if (txx9_pci_option & TXX9_PCI_OPT_PICMG) + irq = (irq + 33 - slot) % 4; + else + irq = (irq + 3 + slot) % 4; } irq++; /* 1-4 */ @@ -66,15 +61,13 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) irq = JMR3927_IRQ_IOC_PCIA; break; case 2: - // wrong for backplane irq = JMR3927_IRQ_IOC_PCIB; - irq = JMR3927_IRQ_IOC_PCID; + irq = JMR3927_IRQ_IOC_PCIB; break; case 3: irq = JMR3927_IRQ_IOC_PCIC; break; case 4: - // wrong for backplane irq = JMR3927_IRQ_IOC_PCID; - irq = JMR3927_IRQ_IOC_PCIB; + irq = JMR3927_IRQ_IOC_PCID; break; } diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index 26013badfe1f..abab4852d158 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -33,102 +33,42 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> +#include <asm/txx9/pci.h> +#include <asm/txx9/rbtx4927.h> -#include <asm/txx9/tx4927.h> - -#undef DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* look up table for backplane pci irq for slots 17-20 by pin # */ -static unsigned char backplane_pci_irq[4][4] = { - /* PJ6 SLOT: 17, PIN: 1 */ {TX4927_IRQ_IOC_PCIA, - /* PJ6 SLOT: 17, PIN: 2 */ - TX4927_IRQ_IOC_PCIB, - /* PJ6 SLOT: 17, PIN: 3 */ - TX4927_IRQ_IOC_PCIC, - /* PJ6 SLOT: 17, PIN: 4 */ - TX4927_IRQ_IOC_PCID}, - /* SB SLOT: 18, PIN: 1 */ {TX4927_IRQ_IOC_PCIB, - /* SB SLOT: 18, PIN: 2 */ - TX4927_IRQ_IOC_PCIC, - /* SB SLOT: 18, PIN: 3 */ - TX4927_IRQ_IOC_PCID, - /* SB SLOT: 18, PIN: 4 */ - TX4927_IRQ_IOC_PCIA}, - /* PJ5 SLOT: 19, PIN: 1 */ {TX4927_IRQ_IOC_PCIC, - /* PJ5 SLOT: 19, PIN: 2 */ - TX4927_IRQ_IOC_PCID, - /* PJ5 SLOT: 19, PIN: 3 */ - TX4927_IRQ_IOC_PCIA, - /* PJ5 SLOT: 19, PIN: 4 */ - TX4927_IRQ_IOC_PCIB}, - /* PJ4 SLOT: 20, PIN: 1 */ {TX4927_IRQ_IOC_PCID, - /* PJ4 SLOT: 20, PIN: 2 */ - TX4927_IRQ_IOC_PCIA, - /* PJ4 SLOT: 20, PIN: 3 */ - TX4927_IRQ_IOC_PCIB, - /* PJ4 SLOT: 20, PIN: 4 */ - TX4927_IRQ_IOC_PCIC} -}; - -static int pci_get_irq(const struct pci_dev *dev, int pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; - DBG("pci_get_irq: pin is %d\n", pin); /* IRQ rotation */ irq--; /* 0-3 */ - if (dev->bus->parent == NULL && - PCI_SLOT(dev->devfn) == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { - printk("Onboard PCI_SLOT(dev->devfn) is %d\n", - PCI_SLOT(dev->devfn)); - /* IDSEL=A23 is tx4927 onboard pci slot */ - irq = (irq + PCI_SLOT(dev->devfn)) % 4; - irq++; /* 1-4 */ - DBG("irq is now %d\n", irq); - - switch (irq) { - case 1: - irq = TX4927_IRQ_IOC_PCIA; - break; - case 2: - irq = TX4927_IRQ_IOC_PCIB; - break; - case 3: - irq = TX4927_IRQ_IOC_PCIC; - break; - case 4: - irq = TX4927_IRQ_IOC_PCID; - break; - } + if (slot == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { + /* PCI CardSlot (IDSEL=A23) */ + /* PCIA => PCIA */ + irq = (irq + 0 + slot) % 4; } else { /* PCI Backplane */ - DBG("PCI Backplane PCI_SLOT(dev->devfn) is %d\n", - PCI_SLOT(dev->devfn)); - irq = backplane_pci_irq[PCI_SLOT(dev->devfn) - 17][irq]; + if (txx9_pci_option & TXX9_PCI_OPT_PICMG) + irq = (irq + 33 - slot) % 4; + else + irq = (irq + 3 + slot) % 4; } - DBG("assigned irq %d\n", irq); - return irq; -} - -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - unsigned char irq; - - printk("PCI Setup for pin %d \n", pin); - - if (dev->device == 0x9130) /* IDE */ - irq = 14; - else - irq = pci_get_irq(dev, pin); + irq++; /* 1-4 */ + switch (irq) { + case 1: + irq = RBTX4927_IRQ_IOC_PCIA; + break; + case 2: + irq = RBTX4927_IRQ_IOC_PCIB; + break; + case 3: + irq = RBTX4927_IRQ_IOC_PCIC; + break; + case 4: + irq = RBTX4927_IRQ_IOC_PCID; + break; + } return irq; } diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c index 64d4510c0265..39c995830384 100644 --- a/arch/mips/pci/fixup-rbtx4938.c +++ b/arch/mips/pci/fixup-rbtx4938.c @@ -10,45 +10,28 @@ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) */ #include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> - +#include <asm/txx9/pci.h> #include <asm/txx9/rbtx4938.h> -extern struct pci_controller tx4938_pci_controller[]; - -static int pci_get_irq(const struct pci_dev *dev, int pin) +int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - int irq = pin; - u8 slot = PCI_SLOT(dev->devfn); - struct pci_controller *controller = (struct pci_controller *)dev->sysdata; - - if (controller == &tx4938_pci_controller[1]) { - /* TX4938 PCIC1 */ - switch (slot) { - case TX4938_PCIC_IDSEL_AD_TO_SLOT(31): - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH0_SEL) - return RBTX4938_IRQ_IRC + TX4938_IR_ETH0; - break; - case TX4938_PCIC_IDSEL_AD_TO_SLOT(30): - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_ETH1_SEL) - return RBTX4938_IRQ_IRC + TX4938_IR_ETH1; - break; - } - return 0; - } + int irq = tx4938_pcic1_map_irq(dev, slot); + if (irq >= 0) + return irq; + irq = pin; /* IRQ rotation */ irq--; /* 0-3 */ - if (dev->bus->parent == NULL && - (slot == TX4938_PCIC_IDSEL_AD_TO_SLOT(23))) { + if (slot == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { /* PCI CardSlot (IDSEL=A23) */ /* PCIA => PCIA (IDSEL=A23) */ irq = (irq + 0 + slot) % 4; } else { /* PCI Backplane */ - irq = (irq + 33 - slot) % 4; + if (txx9_pci_option & TXX9_PCI_OPT_PICMG) + irq = (irq + 33 - slot) % 4; + else + irq = (irq + 3 + slot) % 4; } irq++; /* 1-4 */ @@ -69,19 +52,6 @@ static int pci_get_irq(const struct pci_dev *dev, int pin) return irq; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - unsigned char irq = 0; - - irq = pci_get_irq(dev, pin); - - printk(KERN_INFO "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n", - dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), irq); - - return irq; -} - /* * Do platform specific device initialization at pci_enable_device() time */ diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c index 5d398f694682..8a17a39e5bf2 100644 --- a/arch/mips/pci/ops-tx3927.c +++ b/arch/mips/pci/ops-tx3927.c @@ -8,7 +8,7 @@ * * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c * - * Define the pci_ops for JMR3927. + * Define the pci_ops for TX3927. * * Much of the code is derived from the original DDB5074 port by * Geert Uytterhoeven <geert@sonycom.com> @@ -39,7 +39,7 @@ #include <linux/init.h> #include <asm/addrspace.h> -#include <asm/txx9/jmr3927.h> +#include <asm/txx9/tx3927.h> static inline int mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where) @@ -68,7 +68,7 @@ static inline int check_abort(void) return PCIBIOS_SUCCESSFUL; } -static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, +static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { int ret; @@ -94,7 +94,7 @@ static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, return check_abort(); } -static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, +static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { int ret; @@ -125,7 +125,80 @@ static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, return check_abort(); } -struct pci_ops jmr3927_pci_ops = { - jmr3927_pci_read_config, - jmr3927_pci_write_config, +static struct pci_ops tx3927_pci_ops = { + .read = tx3927_pci_read_config, + .write = tx3927_pci_write_config, }; + +void __init tx3927_pcic_setup(struct pci_controller *channel, + unsigned long sdram_size, int extarb) +{ + unsigned long flags; + unsigned long io_base = + channel->io_resource->start + mips_io_port_base - IO_BASE; + unsigned long io_size = + channel->io_resource->end - channel->io_resource->start; + unsigned long io_pciaddr = + channel->io_resource->start - channel->io_offset; + unsigned long mem_base = + channel->mem_resource->start; + unsigned long mem_size = + channel->mem_resource->end - channel->mem_resource->start; + unsigned long mem_pciaddr = + channel->mem_resource->start - channel->mem_offset; + + printk(KERN_INFO "TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s", + tx3927_pcicptr->did, tx3927_pcicptr->vid, + tx3927_pcicptr->rid, + extarb ? "External" : "Internal"); + channel->pci_ops = &tx3927_pci_ops; + + local_irq_save(flags); + /* Disable External PCI Config. Access */ + tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD; +#ifdef __BIG_ENDIAN + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE | + TX3927_PCIC_LBC_TIBSE | + TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE; +#endif + /* LB->PCI mappings */ + tx3927_pcicptr->iomas = ~(io_size - 1); + tx3927_pcicptr->ilbioma = io_base; + tx3927_pcicptr->ipbioma = io_pciaddr; + tx3927_pcicptr->mmas = ~(mem_size - 1); + tx3927_pcicptr->ilbmma = mem_base; + tx3927_pcicptr->ipbmma = mem_pciaddr; + /* PCI->LB mappings */ + tx3927_pcicptr->iobas = 0xffffffff; + tx3927_pcicptr->ioba = 0; + tx3927_pcicptr->tlbioma = 0; + tx3927_pcicptr->mbas = ~(sdram_size - 1); + tx3927_pcicptr->mba = 0; + tx3927_pcicptr->tlbmma = 0; + /* Enable Direct mapping Address Space Decoder */ + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; + + /* Clear All Local Bus Status */ + tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; + /* Enable All Local Bus Interrupts */ + tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL; + /* Clear All PCI Status Error */ + tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL; + /* Enable All PCI Status Error Interrupts */ + tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL; + + /* PCIC Int => IRC IRQ10 */ + tx3927_pcicptr->il = TX3927_IR_PCI; + /* Target Control (per errata) */ + tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; + + /* Enable Bus Arbiter */ + if (!extarb) + tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; + + tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | + PCI_COMMAND_IO | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + local_irq_restore(flags); +} diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index 54730eee451b..c6b49bccd274 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c @@ -1,206 +1,408 @@ /* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com + * Define the pci_ops for the PCIC on Toshiba TX4927, TX4938, etc. * - * Copyright (C) 2000-2001 Toshiba Corporation - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) - * - * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c - * - * Define the pci_ops for the Toshiba rbtx4927 - * - * Much of the code is derived from the original DDB5074 port by - * Geert Uytterhoeven <geert@sonycom.com> - * - * Copyright 2004 MontaVista Software Inc. - * Author: Manish Lachwani (mlachwani@mvista.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * Based on linux/arch/mips/pci/ops-tx4938.c, + * linux/arch/mips/pci/fixup-rbtx4938.c, + * linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 2003-2005 (c) MontaVista Software, Inc. + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. */ -#include <linux/types.h> -#include <linux/pci.h> #include <linux/kernel.h> -#include <linux/init.h> -#include <asm/txx9/tx4927.h> - -/* initialize in setup */ -struct resource pci_io_resource = { - .name = "TX4927 PCI IO SPACE", - .start = 0x1000, - .end = (0x1000 + (TX4927_PCIIO_SIZE)) - 1, - .flags = IORESOURCE_IO -}; +#include <asm/txx9/tx4927pcic.h> -/* initialize in setup */ -struct resource pci_mem_resource = { - .name = "TX4927 PCI MEM SPACE", - .start = TX4927_PCIMEM, - .end = TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; +static struct { + struct pci_controller *channel; + struct tx4927_pcic_reg __iomem *pcicptr; +} pcicptrs[2]; /* TX4938 has 2 pcic */ + +static void __init set_tx4927_pcicptr(struct pci_controller *channel, + struct tx4927_pcic_reg __iomem *pcicptr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (pcicptrs[i].channel == channel) { + pcicptrs[i].pcicptr = pcicptr; + return; + } + } + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (!pcicptrs[i].channel) { + pcicptrs[i].channel = channel; + pcicptrs[i].pcicptr = pcicptr; + return; + } + } + BUG(); +} -static int mkaddr(int bus, int dev_fn, int where, int *flagsp) +struct tx4927_pcic_reg __iomem *get_tx4927_pcicptr( + struct pci_controller *channel) { - if (bus > 0) { - /* Type 1 configuration */ - tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; - } else { - if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0)) - return -1; + int i; - /* Type 0 configuration */ - tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc); + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (pcicptrs[i].channel == channel) + return pcicptrs[i].pcicptr; } + return NULL; +} + +static int mkaddr(struct pci_bus *bus, unsigned int devfn, int where, + struct tx4927_pcic_reg __iomem *pcicptr) +{ + if (bus->parent == NULL && + devfn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0)) + return -1; + __raw_writel(((bus->number & 0xff) << 0x10) + | ((devfn & 0xff) << 0x08) | (where & 0xfc) + | (bus->parent ? 1 : 0), + &pcicptr->g2pcfgadrs); /* clear M_ABORT and Disable M_ABORT Int. */ - tx4927_pcicptr->pcistatus = - (tx4927_pcicptr->pcistatus & 0x0000ffff) | - (PCI_STATUS_REC_MASTER_ABORT << 16); - tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; + __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) + | (PCI_STATUS_REC_MASTER_ABORT << 16), + &pcicptr->pcistatus); return 0; } -static int check_abort(int flags) +static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr) { int code = PCIBIOS_SUCCESSFUL; - if (tx4927_pcicptr-> - pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { - tx4927_pcicptr->pcistatus = - (tx4927_pcicptr-> - pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT - << 16); - tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; + + /* wait write cycle completion before checking error status */ + while (__raw_readl(&pcicptr->pcicstatus) & TX4927_PCIC_PCICSTATUS_IWB) + ; + if (__raw_readl(&pcicptr->pcistatus) + & (PCI_STATUS_REC_MASTER_ABORT << 16)) { + __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) + | (PCI_STATUS_REC_MASTER_ABORT << 16), + &pcicptr->pcistatus); code = PCIBIOS_DEVICE_NOT_FOUND; } return code; } -static int tx4927_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 * val) +static u8 icd_readb(int offset, struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 3; +#endif + return __raw_readb((void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static u16 icd_readw(int offset, struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 2; +#endif + return __raw_readw((void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static u32 icd_readl(struct tx4927_pcic_reg __iomem *pcicptr) +{ + return __raw_readl(&pcicptr->g2pcfgdata); +} +static void icd_writeb(u8 val, int offset, + struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 3; +#endif + __raw_writeb(val, (void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static void icd_writew(u16 val, int offset, + struct tx4927_pcic_reg __iomem *pcicptr) +{ +#ifdef __BIG_ENDIAN + offset ^= 2; +#endif + __raw_writew(val, (void __iomem *)&pcicptr->g2pcfgdata + offset); +} +static void icd_writel(u32 val, struct tx4927_pcic_reg __iomem *pcicptr) { - int flags, retval, dev, busno, func; + __raw_writel(val, &pcicptr->g2pcfgdata); +} - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); +static struct tx4927_pcic_reg __iomem *pci_bus_to_pcicptr(struct pci_bus *bus) +{ + struct pci_controller *channel = bus->sysdata; + return get_tx4927_pcicptr(channel); +} - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busno = bus->number; - } else { - busno = 0; - } +static int tx4927_pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) +{ + struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus); - if (mkaddr(busno, devfn, where, &flags)) + if (mkaddr(bus, devfn, where, pcicptr)) { + *val = 0xffffffff; return -1; - + } switch (size) { case 1: - *val = *(volatile u8 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)); -#else - ((where & 0x3) ^ 0x3)); -#endif + *val = icd_readb(where & 3, pcicptr); break; case 2: - *val = *(volatile u16 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)); -#else - ((where & 0x3) ^ 0x2)); -#endif - break; - case 4: - *val = tx4927_pcicptr->g2pcfgdata; + *val = icd_readw(where & 3, pcicptr); break; + default: + *val = icd_readl(pcicptr); } + return check_abort(pcicptr); +} - retval = check_abort(flags); - if (retval == PCIBIOS_DEVICE_NOT_FOUND) - *val = 0xffffffff; +static int tx4927_pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus); - return retval; + if (mkaddr(bus, devfn, where, pcicptr)) + return -1; + switch (size) { + case 1: + icd_writeb(val, where & 3, pcicptr); + break; + case 2: + icd_writew(val, where & 3, pcicptr); + break; + default: + icd_writel(val, pcicptr); + } + return check_abort(pcicptr); } -static int tx4927_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) +static struct pci_ops tx4927_pci_ops = { + .read = tx4927_pci_config_read, + .write = tx4927_pci_config_write, +}; + +static struct { + u8 trdyto; + u8 retryto; + u16 gbwc; +} tx4927_pci_opts __devinitdata = { + .trdyto = 0, + .retryto = 0, + .gbwc = 0xfe0, /* 4064 GBUSCLK for CCFG.GTOT=0b11 */ +}; + +void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr, + struct pci_controller *channel, int extarb) { - int flags, dev, busno, func; - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); + int i; + unsigned long flags; - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busno = bus->number; - } else { - busno = 0; - } + set_tx4927_pcicptr(channel, pcicptr); - if (mkaddr(busno, devfn, where, &flags)) - return -1; + if (!channel->pci_ops) + printk(KERN_INFO + "PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + __raw_readl(&pcicptr->pciid) >> 16, + __raw_readl(&pcicptr->pciid) & 0xffff, + __raw_readl(&pcicptr->pciccrev) & 0xff, + extarb ? "External" : "Internal"); + channel->pci_ops = &tx4927_pci_ops; - switch (size) { - case 1: - *(volatile u8 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)) = val; + local_irq_save(flags); + + /* Disable All Initiator Space */ + __raw_writel(__raw_readl(&pcicptr->pciccfg) + & ~(TX4927_PCIC_PCICCFG_G2PMEN(0) + | TX4927_PCIC_PCICCFG_G2PMEN(1) + | TX4927_PCIC_PCICCFG_G2PMEN(2) + | TX4927_PCIC_PCICCFG_G2PIOEN), + &pcicptr->pciccfg); + + /* GB->PCI mappings */ + __raw_writel((channel->io_resource->end - channel->io_resource->start) + >> 4, + &pcicptr->g2piomask); + ____raw_writeq((channel->io_resource->start + + channel->io_map_base - IO_BASE) | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PIOGBASE_ECHG #else - ((where & 0x3) ^ 0x3)) = val; + TX4927_PCIC_G2PIOGBASE_BSDIS #endif - break; - - case 2: - *(volatile u16 *) ((unsigned long) & tx4927_pcicptr-> - g2pcfgdata | -#ifdef __LITTLE_ENDIAN - (where & 3)) = val; + , &pcicptr->g2piogbase); + ____raw_writeq(channel->io_resource->start - channel->io_offset, + &pcicptr->g2piopbase); + for (i = 0; i < 3; i++) { + __raw_writel(0, &pcicptr->g2pmmask[i]); + ____raw_writeq(0, &pcicptr->g2pmgbase[i]); + ____raw_writeq(0, &pcicptr->g2pmpbase[i]); + } + if (channel->mem_resource->end) { + __raw_writel((channel->mem_resource->end + - channel->mem_resource->start) >> 4, + &pcicptr->g2pmmask[0]); + ____raw_writeq(channel->mem_resource->start | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PMnGBASE_ECHG #else - ((where & 0x3) ^ 0x2)) = val; + TX4927_PCIC_G2PMnGBASE_BSDIS #endif - break; - case 4: - tx4927_pcicptr->g2pcfgdata = val; - break; + , &pcicptr->g2pmgbase[0]); + ____raw_writeq(channel->mem_resource->start - + channel->mem_offset, + &pcicptr->g2pmpbase[0]); + } + /* PCI->GB mappings (I/O 256B) */ + __raw_writel(0, &pcicptr->p2giopbase); /* 256B */ + ____raw_writeq(0, &pcicptr->p2giogbase); + /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */ + __raw_writel(0, &pcicptr->p2gm0plbase); + __raw_writel(0, &pcicptr->p2gm0pubase); + ____raw_writeq(TX4927_PCIC_P2GMnGBASE_TMEMEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GMnGBASE_TECHG +#else + TX4927_PCIC_P2GMnGBASE_TBSDIS +#endif + , &pcicptr->p2gmgbase[0]); + /* PCI->GB mappings (MEM 16MB) */ + __raw_writel(0xffffffff, &pcicptr->p2gm1plbase); + __raw_writel(0xffffffff, &pcicptr->p2gm1pubase); + ____raw_writeq(0, &pcicptr->p2gmgbase[1]); + /* PCI->GB mappings (MEM 1MB) */ + __raw_writel(0xffffffff, &pcicptr->p2gm2pbase); /* 1MB */ + ____raw_writeq(0, &pcicptr->p2gmgbase[2]); + + /* Clear all (including IRBER) except for GBWC */ + __raw_writel((tx4927_pci_opts.gbwc << 16) + & TX4927_PCIC_PCICCFG_GBWC_MASK, + &pcicptr->pciccfg); + /* Enable Initiator Memory Space */ + if (channel->mem_resource->end) + __raw_writel(__raw_readl(&pcicptr->pciccfg) + | TX4927_PCIC_PCICCFG_G2PMEN(0), + &pcicptr->pciccfg); + /* Enable Initiator I/O Space */ + if (channel->io_resource->end) + __raw_writel(__raw_readl(&pcicptr->pciccfg) + | TX4927_PCIC_PCICCFG_G2PIOEN, + &pcicptr->pciccfg); + /* Enable Initiator Config */ + __raw_writel(__raw_readl(&pcicptr->pciccfg) + | TX4927_PCIC_PCICCFG_ICAEN | TX4927_PCIC_PCICCFG_TCAR, + &pcicptr->pciccfg); + + /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ + __raw_writel(0, &pcicptr->pcicfg1); + + __raw_writel((__raw_readl(&pcicptr->g2ptocnt) & ~0xffff) + | (tx4927_pci_opts.trdyto & 0xff) + | ((tx4927_pci_opts.retryto & 0xff) << 8), + &pcicptr->g2ptocnt); + + /* Clear All Local Bus Status */ + __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicstatus); + /* Enable All Local Bus Interrupts */ + __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicmask); + /* Clear All Initiator Status */ + __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pstatus); + /* Enable All Initiator Interrupts */ + __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pmask); + /* Clear All PCI Status Error */ + __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff) + | (TX4927_PCIC_PCISTATUS_ALL << 16), + &pcicptr->pcistatus); + /* Enable All PCI Status Error Interrupts */ + __raw_writel(TX4927_PCIC_PCISTATUS_ALL, &pcicptr->pcimask); + + if (!extarb) { + /* Reset Bus Arbiter */ + __raw_writel(TX4927_PCIC_PBACFG_RPBA, &pcicptr->pbacfg); + __raw_writel(0, &pcicptr->pbabm); + /* Enable Bus Arbiter */ + __raw_writel(TX4927_PCIC_PBACFG_PBAEN, &pcicptr->pbacfg); } - return check_abort(flags); + __raw_writel(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY + | PCI_COMMAND_PARITY | PCI_COMMAND_SERR, + &pcicptr->pcistatus); + local_irq_restore(flags); + + printk(KERN_DEBUG + "PCI: COMMAND=%04x,PCIMASK=%04x," + "TRDYTO=%02x,RETRYTO=%02x,GBWC=%03x\n", + __raw_readl(&pcicptr->pcistatus) & 0xffff, + __raw_readl(&pcicptr->pcimask) & 0xffff, + __raw_readl(&pcicptr->g2ptocnt) & 0xff, + (__raw_readl(&pcicptr->g2ptocnt) & 0xff00) >> 8, + (__raw_readl(&pcicptr->pciccfg) >> 16) & 0xfff); } -struct pci_ops tx4927_pci_ops = { - tx4927_pcibios_read_config, - tx4927_pcibios_write_config -}; +static void tx4927_report_pcic_status1(struct tx4927_pcic_reg __iomem *pcicptr) +{ + __u16 pcistatus = (__u16)(__raw_readl(&pcicptr->pcistatus) >> 16); + __u32 g2pstatus = __raw_readl(&pcicptr->g2pstatus); + __u32 pcicstatus = __raw_readl(&pcicptr->pcicstatus); + static struct { + __u32 flag; + const char *str; + } pcistat_tbl[] = { + { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" }, + { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" }, + { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" }, + { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" }, + { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" }, + { PCI_STATUS_PARITY, "MasterParityError" }, + }, g2pstat_tbl[] = { + { TX4927_PCIC_G2PSTATUS_TTOE, "TIOE" }, + { TX4927_PCIC_G2PSTATUS_RTOE, "RTOE" }, + }, pcicstat_tbl[] = { + { TX4927_PCIC_PCICSTATUS_PME, "PME" }, + { TX4927_PCIC_PCICSTATUS_TLB, "TLB" }, + { TX4927_PCIC_PCICSTATUS_NIB, "NIB" }, + { TX4927_PCIC_PCICSTATUS_ZIB, "ZIB" }, + { TX4927_PCIC_PCICSTATUS_PERR, "PERR" }, + { TX4927_PCIC_PCICSTATUS_SERR, "SERR" }, + { TX4927_PCIC_PCICSTATUS_GBE, "GBE" }, + { TX4927_PCIC_PCICSTATUS_IWB, "IWB" }, + }; + int i, cont; -/* - * h/w only supports devices 0x00 to 0x14 - */ -struct pci_controller tx4927_controller = { - .pci_ops = &tx4927_pci_ops, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, -}; + printk(KERN_ERR ""); + if (pcistatus & TX4927_PCIC_PCISTATUS_ALL) { + printk(KERN_CONT "pcistat:%04x(", pcistatus); + for (i = 0, cont = 0; i < ARRAY_SIZE(pcistat_tbl); i++) + if (pcistatus & pcistat_tbl[i].flag) + printk(KERN_CONT "%s%s", + cont++ ? " " : "", pcistat_tbl[i].str); + printk(KERN_CONT ") "); + } + if (g2pstatus & TX4927_PCIC_G2PSTATUS_ALL) { + printk(KERN_CONT "g2pstatus:%08x(", g2pstatus); + for (i = 0, cont = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) + if (g2pstatus & g2pstat_tbl[i].flag) + printk(KERN_CONT "%s%s", + cont++ ? " " : "", g2pstat_tbl[i].str); + printk(KERN_CONT ") "); + } + if (pcicstatus & TX4927_PCIC_PCICSTATUS_ALL) { + printk(KERN_CONT "pcicstatus:%08x(", pcicstatus); + for (i = 0, cont = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) + if (pcicstatus & pcicstat_tbl[i].flag) + printk(KERN_CONT "%s%s", + cont++ ? " " : "", pcicstat_tbl[i].str); + printk(KERN_CONT ")"); + } + printk(KERN_CONT "\n"); +} + +void tx4927_report_pcic_status(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) { + if (pcicptrs[i].pcicptr) + tx4927_report_pcic_status1(pcicptrs[i].pcicptr); + } +} diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c deleted file mode 100644 index 34494b82cb22..000000000000 --- a/arch/mips/pci/ops-tx4938.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Define the pci_ops for the Toshiba rbtx4938 - * Copyright (C) 2000-2001 Toshiba Corporation - * - * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is - * licensed "as is" without any warranty of any kind, whether express - * or implied. - * - * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) - */ -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> - -#include <asm/addrspace.h> -#include <asm/txx9/rbtx4938.h> - -/* initialize in setup */ -struct resource pci_io_resource = { - .name = "pci IO space", - .start = 0, - .end = 0, - .flags = IORESOURCE_IO -}; - -/* initialize in setup */ -struct resource pci_mem_resource = { - .name = "pci memory space", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM -}; - -struct resource tx4938_pcic1_pci_io_resource = { - .name = "PCI1 IO", - .start = 0, - .end = 0, - .flags = IORESOURCE_IO -}; -struct resource tx4938_pcic1_pci_mem_resource = { - .name = "PCI1 mem", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM -}; - -static int mkaddr(int bus, int dev_fn, int where, - struct tx4938_pcic_reg *pcicptr) -{ - if (bus > 0) { - /* Type 1 configuration */ - pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; - } else { - if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0)) - return -1; - - /* Type 0 configuration */ - pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | - ((dev_fn & 0xff) << 0x08) | (where & 0xfc); - } - /* clear M_ABORT and Disable M_ABORT Int. */ - pcicptr->pcistatus = - (pcicptr->pcistatus & 0x0000ffff) | - (PCI_STATUS_REC_MASTER_ABORT << 16); - pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; - - return 0; -} - -static int check_abort(struct tx4938_pcic_reg *pcicptr) -{ - int code = PCIBIOS_SUCCESSFUL; - /* wait write cycle completion before checking error status */ - while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) - ; - if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { - pcicptr->pcistatus = - (pcicptr-> - pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT - << 16); - pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; - code = PCIBIOS_DEVICE_NOT_FOUND; - } - return code; -} - -extern struct pci_controller tx4938_pci_controller[]; -extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch); - -static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus) -{ - struct pci_controller *channel = bus->sysdata; - return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]); -} - -static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 * val) -{ - int retval, dev, busno, func; - struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); - void __iomem *cfgdata = - (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; - - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* check if the bus is top-level */ - if (bus->parent != NULL) - busno = bus->number; - else { - busno = 0; - } - - if (mkaddr(busno, devfn, where, pcicptr)) - return -1; - - switch (size) { - case 1: -#ifdef __BIG_ENDIAN - cfgdata += (where & 3) ^ 3; -#else - cfgdata += where & 3; -#endif - *val = __raw_readb(cfgdata); - break; - case 2: -#ifdef __BIG_ENDIAN - cfgdata += (where & 2) ^ 2; -#else - cfgdata += where & 2; -#endif - *val = __raw_readw(cfgdata); - break; - case 4: - *val = __raw_readl(cfgdata); - break; - } - - retval = check_abort(pcicptr); - if (retval == PCIBIOS_DEVICE_NOT_FOUND) - *val = 0xffffffff; - - return retval; -} - -static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - int dev, busno, func; - struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus); - void __iomem *cfgdata = - (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata; - - busno = bus->number; - dev = PCI_SLOT(devfn); - func = PCI_FUNC(devfn); - - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busno = bus->number; - } else { - busno = 0; - } - - if (mkaddr(busno, devfn, where, pcicptr)) - return -1; - - switch (size) { - case 1: -#ifdef __BIG_ENDIAN - cfgdata += (where & 3) ^ 3; -#else - cfgdata += where & 3; -#endif - __raw_writeb(val, cfgdata); - break; - case 2: -#ifdef __BIG_ENDIAN - cfgdata += (where & 2) ^ 2; -#else - cfgdata += where & 2; -#endif - __raw_writew(val, cfgdata); - break; - case 4: - __raw_writel(val, cfgdata); - break; - } - - return check_abort(pcicptr); -} - -struct pci_ops tx4938_pci_ops = { - tx4938_pcibios_read_config, - tx4938_pcibios_write_config -}; - -struct pci_controller tx4938_pci_controller[] = { - /* h/w only supports devices 0x00 to 0x14 */ - { - .pci_ops = &tx4938_pci_ops, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, - }, - /* h/w only supports devices 0x00 to 0x14 */ - { - .pci_ops = &tx4938_pci_ops, - .io_resource = &tx4938_pcic1_pci_io_resource, - .mem_resource = &tx4938_pcic1_pci_mem_resource, - } -}; diff --git a/arch/mips/pci/pci-jmr3927.c b/arch/mips/pci/pci-jmr3927.c deleted file mode 100644 index 7fb6bd71901a..000000000000 --- a/arch/mips/pci/pci-jmr3927.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * Copyright (C) 2000-2001 Toshiba Corporation - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> - -#include <asm/txx9/jmr3927.h> -#include <asm/debug.h> - -struct resource pci_io_resource = { - .name = "IO MEM", - .start = 0x1000, /* reserve regacy I/O space */ - .end = 0x1000 + JMR3927_PCIIO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -struct resource pci_mem_resource = { - .name = "PCI MEM", - .start = JMR3927_PCIMEM, - .end = JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops jmr3927_pci_ops; - -struct pci_controller jmr3927_controller = { - .pci_ops = &jmr3927_pci_ops, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, - .mem_offset = JMR3927_PCIMEM -}; diff --git a/arch/mips/pci/pci-tx4927.c b/arch/mips/pci/pci-tx4927.c new file mode 100644 index 000000000000..27e86a09dd41 --- /dev/null +++ b/arch/mips/pci/pci-tx4927.c @@ -0,0 +1,83 @@ +/* + * linux/arch/mips/pci/pci-tx4927.c + * + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001, 2003-2005 MontaVista Software Inc. + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <asm/txx9/generic.h> +#include <asm/txx9/tx4927.h> + +int __init tx4927_report_pciclk(void) +{ + int pciclk = 0; + + printk(KERN_INFO "PCIC --%s PCICLK:", + (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66) ? + " PCI66" : ""); + if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) { + u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg); + switch ((unsigned long)ccfg & + TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + pciclk = txx9_cpu_clock * 2 / 5; break; + case TX4927_CCFG_PCIDIVMODE_3: + pciclk = txx9_cpu_clock / 3; break; + case TX4927_CCFG_PCIDIVMODE_5: + pciclk = txx9_cpu_clock / 5; break; + case TX4927_CCFG_PCIDIVMODE_6: + pciclk = txx9_cpu_clock / 6; break; + } + printk("Internal(%u.%uMHz)", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); + } else { + printk("External"); + pciclk = -1; + } + printk("\n"); + return pciclk; +} + +int __init tx4927_pciclk66_setup(void) +{ + int pciclk; + + /* Assert M66EN */ + tx4927_ccfg_set(TX4927_CCFG_PCI66); + /* Double PCICLK (if possible) */ + if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = 0; + u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg); + pcidivmode = (unsigned long)ccfg & + TX4927_CCFG_PCIDIVMODE_MASK; + switch (pcidivmode) { + case TX4927_CCFG_PCIDIVMODE_5: + case TX4927_CCFG_PCIDIVMODE_2_5: + pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5; + pciclk = txx9_cpu_clock * 2 / 5; + break; + case TX4927_CCFG_PCIDIVMODE_6: + case TX4927_CCFG_PCIDIVMODE_3: + default: + pcidivmode = TX4927_CCFG_PCIDIVMODE_3; + pciclk = txx9_cpu_clock / 3; + } + tx4927_ccfg_change(TX4927_CCFG_PCIDIVMODE_MASK, + pcidivmode); + printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", + (unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg)); + } else + pciclk = -1; + return pciclk; +} diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c new file mode 100644 index 000000000000..e5375511c2b7 --- /dev/null +++ b/arch/mips/pci/pci-tx4938.c @@ -0,0 +1,134 @@ +/* + * linux/arch/mips/pci/pci-tx4938.c + * + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001, 2003-2005 MontaVista Software Inc. + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007 + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <asm/txx9/generic.h> +#include <asm/txx9/tx4938.h> + +int __init tx4938_report_pciclk(void) +{ + int pciclk = 0; + + printk(KERN_INFO "PCIC --%s PCICLK:", + (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) ? + " PCI66" : ""); + if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { + u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); + switch ((unsigned long)ccfg & + TX4938_CCFG_PCIDIVMODE_MASK) { + case TX4938_CCFG_PCIDIVMODE_4: + pciclk = txx9_cpu_clock / 4; break; + case TX4938_CCFG_PCIDIVMODE_4_5: + pciclk = txx9_cpu_clock * 2 / 9; break; + case TX4938_CCFG_PCIDIVMODE_5: + pciclk = txx9_cpu_clock / 5; break; + case TX4938_CCFG_PCIDIVMODE_5_5: + pciclk = txx9_cpu_clock * 2 / 11; break; + case TX4938_CCFG_PCIDIVMODE_8: + pciclk = txx9_cpu_clock / 8; break; + case TX4938_CCFG_PCIDIVMODE_9: + pciclk = txx9_cpu_clock / 9; break; + case TX4938_CCFG_PCIDIVMODE_10: + pciclk = txx9_cpu_clock / 10; break; + case TX4938_CCFG_PCIDIVMODE_11: + pciclk = txx9_cpu_clock / 11; break; + } + printk("Internal(%u.%uMHz)", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); + } else { + printk("External"); + pciclk = -1; + } + printk("\n"); + return pciclk; +} + +void __init tx4938_report_pci1clk(void) +{ + __u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); + unsigned int pciclk = + txx9_gbus_clock / ((ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2); + + printk(KERN_INFO "PCIC1 -- %sPCICLK:%u.%uMHz\n", + (ccfg & TX4938_CCFG_PCI1_66) ? "PCI66 " : "", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); +} + +int __init tx4938_pciclk66_setup(void) +{ + int pciclk; + + /* Assert M66EN */ + tx4938_ccfg_set(TX4938_CCFG_PCI66); + /* Double PCICLK (if possible) */ + if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = 0; + u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg); + pcidivmode = (unsigned long)ccfg & + TX4938_CCFG_PCIDIVMODE_MASK; + switch (pcidivmode) { + case TX4938_CCFG_PCIDIVMODE_8: + case TX4938_CCFG_PCIDIVMODE_4: + pcidivmode = TX4938_CCFG_PCIDIVMODE_4; + pciclk = txx9_cpu_clock / 4; + break; + case TX4938_CCFG_PCIDIVMODE_9: + case TX4938_CCFG_PCIDIVMODE_4_5: + pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5; + pciclk = txx9_cpu_clock * 2 / 9; + break; + case TX4938_CCFG_PCIDIVMODE_10: + case TX4938_CCFG_PCIDIVMODE_5: + pcidivmode = TX4938_CCFG_PCIDIVMODE_5; + pciclk = txx9_cpu_clock / 5; + break; + case TX4938_CCFG_PCIDIVMODE_11: + case TX4938_CCFG_PCIDIVMODE_5_5: + default: + pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5; + pciclk = txx9_cpu_clock * 2 / 11; + break; + } + tx4938_ccfg_change(TX4938_CCFG_PCIDIVMODE_MASK, + pcidivmode); + printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", + (unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg)); + } else + pciclk = -1; + return pciclk; +} + +int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +{ + if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { + switch (slot) { + case TX4927_PCIC_IDSEL_AD_TO_SLOT(31): + if (__raw_readq(&tx4938_ccfgptr->pcfg) & + TX4938_PCFG_ETH0_SEL) + return TXX9_IRQ_BASE + TX4938_IR_ETH0; + break; + case TX4927_PCIC_IDSEL_AD_TO_SLOT(30): + if (__raw_readq(&tx4938_ccfgptr->pcfg) & + TX4938_PCFG_ETH1_SEL) + return TXX9_IRQ_BASE + TX4938_IR_ETH1; + break; + } + return 0; + } + return -1; +} |