diff options
Diffstat (limited to 'arch/mips/pci')
-rw-r--r-- | arch/mips/pci/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/pci/fixup-emma2rh.c | 1 | ||||
-rw-r--r-- | arch/mips/pci/ops-pnx8550.c | 2 | ||||
-rw-r--r-- | arch/mips/pci/pci-emma2rh.c | 1 | ||||
-rw-r--r-- | arch/mips/pci/pci-tx4938.c | 2 | ||||
-rw-r--r-- | arch/mips/pci/pci-tx4939.c | 109 | ||||
-rw-r--r-- | arch/mips/pci/pci.c | 80 |
7 files changed, 164 insertions, 32 deletions
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c8c32f4..b188624 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o +obj-$(CONFIG_SOC_TX4939) += pci-tx4939.o obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c index a270589..846eae9 100644 --- a/arch/mips/pci/fixup-emma2rh.c +++ b/arch/mips/pci/fixup-emma2rh.c @@ -29,7 +29,6 @@ #include <linux/pci.h> #include <asm/bootinfo.h> -#include <asm/debug.h> #include <asm/emma2rh/emma2rh.h> diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c index 0e160d9f0..1e6213f 100644 --- a/arch/mips/pci/ops-pnx8550.c +++ b/arch/mips/pci/ops-pnx8550.c @@ -29,8 +29,6 @@ #include <asm/mach-pnx8550/pci.h> #include <asm/mach-pnx8550/glb.h> -#include <asm/debug.h> - static inline void clear_status(void) { diff --git a/arch/mips/pci/pci-emma2rh.c b/arch/mips/pci/pci-emma2rh.c index d99591a..772e283 100644 --- a/arch/mips/pci/pci-emma2rh.c +++ b/arch/mips/pci/pci-emma2rh.c @@ -29,7 +29,6 @@ #include <linux/pci.h> #include <asm/bootinfo.h> -#include <asm/debug.h> #include <asm/emma2rh/emma2rh.h> diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c index 60e2c52..1ea257b 100644 --- a/arch/mips/pci/pci-tx4938.c +++ b/arch/mips/pci/pci-tx4938.c @@ -114,7 +114,7 @@ int __init tx4938_pciclk66_setup(void) return pciclk; } -int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) { if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { switch (slot) { diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c new file mode 100644 index 0000000..5fecf1c --- /dev/null +++ b/arch/mips/pci/pci-tx4939.c @@ -0,0 +1,109 @@ +/* + * linux/arch/mips/pci/pci-tx4939.c + * + * Based on linux/arch/mips/txx9/rbtx4939/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 <linux/interrupt.h> +#include <asm/txx9/generic.h> +#include <asm/txx9/tx4939.h> + +int __init tx4939_report_pciclk(void) +{ + int pciclk = 0; + + pr_info("PCIC --%s PCICLK:", + (__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66) ? + " PCI66" : ""); + if (__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_PCICLKEN_ALL) { + pciclk = txx9_master_clock * 20 / 6; + if (!(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66)) + pciclk /= 2; + printk(KERN_CONT "Internal(%u.%uMHz)", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); + } else { + printk(KERN_CONT "External"); + pciclk = -1; + } + printk(KERN_CONT "\n"); + return pciclk; +} + +void __init tx4939_report_pci1clk(void) +{ + unsigned int pciclk = txx9_master_clock * 20 / 6; + + pr_info("PCIC1 -- PCICLK:%u.%uMHz\n", + (pciclk + 50000) / 1000000, + ((pciclk + 50000) / 100000) % 10); +} + +int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +{ + if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) { + switch (slot) { + case TX4927_PCIC_IDSEL_AD_TO_SLOT(31): + if (__raw_readq(&tx4939_ccfgptr->pcfg) & + TX4939_PCFG_ET0MODE) + return TXX9_IRQ_BASE + TX4939_IR_ETH(0); + break; + case TX4927_PCIC_IDSEL_AD_TO_SLOT(30): + if (__raw_readq(&tx4939_ccfgptr->pcfg) & + TX4939_PCFG_ET1MODE) + return TXX9_IRQ_BASE + TX4939_IR_ETH(1); + break; + } + return 0; + } + return -1; +} + +int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = tx4939_pcic1_map_irq(dev, slot); + + if (irq >= 0) + return irq; + irq = pin; + /* IRQ rotation */ + irq--; /* 0-3 */ + irq = (irq + 33 - slot) % 4; + irq++; /* 1-4 */ + + switch (irq) { + case 1: + irq = TXX9_IRQ_BASE + TX4939_IR_INTA; + break; + case 2: + irq = TXX9_IRQ_BASE + TX4939_IR_INTB; + break; + case 3: + irq = TXX9_IRQ_BASE + TX4939_IR_INTC; + break; + case 4: + irq = TXX9_IRQ_BASE + TX4939_IR_INTD; + break; + } + return irq; +} + +void __init tx4939_setup_pcierr_irq(void) +{ + if (request_irq(TXX9_IRQ_BASE + TX4939_IR_PCIERR, + tx4927_pcierr_interrupt, + IRQF_DISABLED, "PCI error", + (void *)TX4939_PCIC_REG)) + pr_warning("Failed to request irq for PCIERR\n"); +} diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index c7fe6ec..a377e9d 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -34,6 +34,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head; unsigned long PCIBIOS_MIN_IO = 0x0000; unsigned long PCIBIOS_MIN_MEM = 0; +static int pci_initialized; + /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -74,6 +76,42 @@ pcibios_align_resource(void *data, struct resource *res, res->start = start; } +static void __devinit pcibios_scanbus(struct pci_controller *hose) +{ + static int next_busno; + static int need_domain_info; + struct pci_bus *bus; + + if (!hose->iommu) + PCI_DMA_BUS_IS_PHYS = 1; + + if (hose->get_busno && pci_probe_only) + next_busno = (*hose->get_busno)(); + + bus = pci_scan_bus(next_busno, hose->pci_ops, hose); + hose->bus = bus; + + need_domain_info = need_domain_info || hose->index; + hose->need_domain_info = need_domain_info; + if (bus) { + next_busno = bus->subordinate + 1; + /* Don't allow 8-bit bus number overflow inside the hose - + reserve some space for bridges. */ + if (next_busno > 224) { + next_busno = 0; + need_domain_info = 1; + } + + if (!pci_probe_only) { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + pci_enable_bridges(bus); + } + } +} + +static DEFINE_MUTEX(pci_scan_mutex); + void __devinit register_pci_controller(struct pci_controller *hose) { if (request_resource(&iomem_resource, hose->mem_resource) < 0) @@ -93,6 +131,17 @@ void __devinit register_pci_controller(struct pci_controller *hose) printk(KERN_WARNING "registering PCI controller with io_map_base unset\n"); } + + /* + * Scan the bus if it is register after the PCI subsystem + * initialization. + */ + if (pci_initialized) { + mutex_lock(&pci_scan_mutex); + pcibios_scanbus(hose); + mutex_unlock(&pci_scan_mutex); + } + return; out: @@ -125,38 +174,15 @@ static u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) static int __init pcibios_init(void) { struct pci_controller *hose; - struct pci_bus *bus; - int next_busno; - int need_domain_info = 0; /* Scan all of the recorded PCI controllers. */ - for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { - - if (!hose->iommu) - PCI_DMA_BUS_IS_PHYS = 1; - - if (hose->get_busno && pci_probe_only) - next_busno = (*hose->get_busno)(); - - bus = pci_scan_bus(next_busno, hose->pci_ops, hose); - hose->bus = bus; - need_domain_info = need_domain_info || hose->index; - hose->need_domain_info = need_domain_info; - if (bus) { - next_busno = bus->subordinate + 1; - /* Don't allow 8-bit bus number overflow inside the hose - - reserve some space for bridges. */ - if (next_busno > 224) { - next_busno = 0; - need_domain_info = 1; - } - } - } + for (hose = hose_head; hose; hose = hose->next) + pcibios_scanbus(hose); - if (!pci_probe_only) - pci_assign_unassigned_resources(); pci_fixup_irqs(common_swizzle, pcibios_map_irq); + pci_initialized = 1; + return 0; } |