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/txx9 | |
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/txx9')
-rw-r--r-- | arch/mips/txx9/Kconfig | 11 | ||||
-rw-r--r-- | arch/mips/txx9/generic/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/txx9/generic/pci.c | 377 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup.c | 51 | ||||
-rw-r--r-- | arch/mips/txx9/jmr3927/irq.c | 2 | ||||
-rw-r--r-- | arch/mips/txx9/jmr3927/setup.c | 108 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4927/irq.c | 20 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4927/setup.c | 499 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4938/setup.c | 667 |
9 files changed, 689 insertions, 1048 deletions
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 98d103402b10..b8cdb192543a 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -1,6 +1,12 @@ config TOSHIBA_FPCIB0 bool "FPCIB0 Backplane Support" - depends on TOSHIBA_RBTX4927 + depends on PCI && (SYS_HAS_CPU_TX49XX || SYS_HAS_CPU_TX39XX) + select I8259 + +config PICMG_PCI_BACKPLANE_DEFAULT + bool "Support for PICMG PCI Backplane" + depends on PCI && (SYS_HAS_CPU_TX49XX || SYS_HAS_CPU_TX39XX) + default y if !TOSHIBA_FPCIB0 if TOSHIBA_RBTX4938 @@ -26,3 +32,6 @@ config TX4938_NAND_BOOT Select this option if you need to use NAND boot. endif + +config PCI_TX4927 + bool diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index 8cb4a7e81473..b80b6e072284 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -2,6 +2,8 @@ # Makefile for common code for TXx9 based systems # +obj-y += setup.o +obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_TOSHIBA_RBTX4927) += mem_tx4927.o irq_tx4927.o obj-$(CONFIG_TOSHIBA_RBTX4938) += mem_tx4938.o irq_tx4938.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c new file mode 100644 index 000000000000..8173faab99bb --- /dev/null +++ b/arch/mips/txx9/generic/pci.c @@ -0,0 +1,377 @@ +/* + * linux/arch/mips/txx9/pci.c + * + * Based on linux/arch/mips/txx9/rbtx4927/setup.c, + * linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * Copyright 2001-2005 MontaVista Software Inc. + * Copyright (C) 1996, 97, 2001, 04 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/delay.h> +#include <linux/jiffies.h> +#include <linux/io.h> +#include <asm/txx9/pci.h> +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include <linux/interrupt.h> +#include <asm/i8259.h> +#include <asm/txx9/smsc_fdc37m81x.h> +#endif + +static int __init +early_read_config_word(struct pci_controller *hose, + int top_bus, int bus, int devfn, int offset, u16 *value) +{ + struct pci_dev fake_dev; + struct pci_bus fake_bus; + + fake_dev.bus = &fake_bus; + fake_dev.sysdata = hose; + fake_dev.devfn = devfn; + fake_bus.number = bus; + fake_bus.sysdata = hose; + fake_bus.ops = hose->pci_ops; + + if (bus != top_bus) + /* Fake a parent bus structure. */ + fake_bus.parent = &fake_bus; + else + fake_bus.parent = NULL; + + return pci_read_config_word(&fake_dev, offset, value); +} + +int __init txx9_pci66_check(struct pci_controller *hose, int top_bus, + int current_bus) +{ + u32 pci_devfn; + unsigned short vid; + int cap66 = -1; + u16 stat; + + /* It seems SLC90E66 needs some time after PCI reset... */ + mdelay(80); + + printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n"); + + for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) { + if (PCI_FUNC(pci_devfn)) + continue; + if (early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_VENDOR_ID, &vid) != + PCIBIOS_SUCCESSFUL) + continue; + if (vid == 0xffff) + continue; + + /* check 66MHz capability */ + if (cap66 < 0) + cap66 = 1; + if (cap66) { + early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_STATUS, &stat); + if (!(stat & PCI_STATUS_66MHZ)) { + printk(KERN_DEBUG + "PCI: %02x:%02x not 66MHz capable.\n", + current_bus, pci_devfn); + cap66 = 0; + break; + } + } + } + return cap66 > 0; +} + +static struct resource primary_pci_mem_res[2] = { + { .name = "PCI MEM" }, + { .name = "PCI MMIO" }, +}; +static struct resource primary_pci_io_res = { .name = "PCI IO" }; +struct pci_controller txx9_primary_pcic = { + .mem_resource = &primary_pci_mem_res[0], + .io_resource = &primary_pci_io_res, +}; + +#ifdef CONFIG_64BIT +int txx9_pci_mem_high __initdata = 1; +#else +int txx9_pci_mem_high __initdata; +#endif + +/* + * allocate pci_controller and resources. + * mem_base, io_base: physical addresss. 0 for auto assignment. + * mem_size and io_size means max size on auto assignment. + * pcic must be &txx9_primary_pcic or NULL. + */ +struct pci_controller *__init +txx9_alloc_pci_controller(struct pci_controller *pcic, + unsigned long mem_base, unsigned long mem_size, + unsigned long io_base, unsigned long io_size) +{ + struct pcic { + struct pci_controller c; + struct resource r_mem[2]; + struct resource r_io; + } *new = NULL; + int min_size = 0x10000; + + if (!pcic) { + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + new->r_mem[0].name = "PCI mem"; + new->r_mem[1].name = "PCI mmio"; + new->r_io.name = "PCI io"; + new->c.mem_resource = new->r_mem; + new->c.io_resource = &new->r_io; + pcic = &new->c; + } else + BUG_ON(pcic != &txx9_primary_pcic); + pcic->io_resource->flags = IORESOURCE_IO; + + /* + * for auto assignment, first search a (big) region for PCI + * MEM, then search a region for PCI IO. + */ + if (mem_base) { + pcic->mem_resource[0].start = mem_base; + pcic->mem_resource[0].end = mem_base + mem_size - 1; + if (request_resource(&iomem_resource, &pcic->mem_resource[0])) + goto free_and_exit; + } else { + unsigned long min = 0, max = 0x20000000; /* low 512MB */ + if (!mem_size) { + /* default size for auto assignment */ + if (txx9_pci_mem_high) + mem_size = 0x20000000; /* mem:512M(max) */ + else + mem_size = 0x08000000; /* mem:128M(max) */ + } + if (txx9_pci_mem_high) { + min = 0x20000000; + max = 0xe0000000; + } + /* search free region for PCI MEM */ + for (; mem_size >= min_size; mem_size /= 2) { + if (allocate_resource(&iomem_resource, + &pcic->mem_resource[0], + mem_size, min, max, + mem_size, NULL, NULL) == 0) + break; + } + if (mem_size < min_size) + goto free_and_exit; + } + + pcic->mem_resource[1].flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (io_base) { + pcic->mem_resource[1].start = io_base; + pcic->mem_resource[1].end = io_base + io_size - 1; + if (request_resource(&iomem_resource, &pcic->mem_resource[1])) + goto release_and_exit; + } else { + if (!io_size) + /* default size for auto assignment */ + io_size = 0x01000000; /* io:16M(max) */ + /* search free region for PCI IO in low 512MB */ + for (; io_size >= min_size; io_size /= 2) { + if (allocate_resource(&iomem_resource, + &pcic->mem_resource[1], + io_size, 0, 0x20000000, + io_size, NULL, NULL) == 0) + break; + } + if (io_size < min_size) + goto release_and_exit; + io_base = pcic->mem_resource[1].start; + } + + pcic->mem_resource[0].flags = IORESOURCE_MEM; + if (pcic == &txx9_primary_pcic && + mips_io_port_base == (unsigned long)-1) { + /* map ioport 0 to PCI I/O space address 0 */ + set_io_port_base(IO_BASE + pcic->mem_resource[1].start); + pcic->io_resource->start = 0; + pcic->io_offset = 0; /* busaddr == ioaddr */ + pcic->io_map_base = IO_BASE + pcic->mem_resource[1].start; + } else { + /* physaddr to ioaddr */ + pcic->io_resource->start = + io_base - (mips_io_port_base - IO_BASE); + pcic->io_offset = io_base - (mips_io_port_base - IO_BASE); + pcic->io_map_base = mips_io_port_base; + } + pcic->io_resource->end = pcic->io_resource->start + io_size - 1; + + pcic->mem_offset = 0; /* busaddr == physaddr */ + + printk(KERN_INFO "PCI: IO 0x%08llx-0x%08llx MEM 0x%08llx-0x%08llx\n", + (unsigned long long)pcic->mem_resource[1].start, + (unsigned long long)pcic->mem_resource[1].end, + (unsigned long long)pcic->mem_resource[0].start, + (unsigned long long)pcic->mem_resource[0].end); + + /* register_pci_controller() will request MEM resource */ + release_resource(&pcic->mem_resource[0]); + return pcic; + release_and_exit: + release_resource(&pcic->mem_resource[0]); + free_and_exit: + kfree(new); + printk(KERN_ERR "PCI: Failed to allocate resources.\n"); + return NULL; +} + +static int __init +txx9_arch_pci_init(void) +{ + PCIBIOS_MIN_IO = 0x8000; /* reseve legacy I/O space */ + return 0; +} +arch_initcall(txx9_arch_pci_init); + +/* IRQ/IDSEL mapping */ +int txx9_pci_option = +#ifdef CONFIG_PICMG_PCI_BACKPLANE_DEFAULT + TXX9_PCI_OPT_PICMG | +#endif + TXX9_PCI_OPT_CLK_AUTO; + +enum txx9_pci_err_action txx9_pci_err_action = TXX9_PCI_ERR_REPORT; + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static irqreturn_t i8259_interrupt(int irq, void *dev_id) +{ + int isairq; + + isairq = i8259_irq(); + if (unlikely(isairq <= I8259A_IRQ_BASE)) + return IRQ_NONE; + generic_handle_irq(isairq); + return IRQ_HANDLED; +} + +static int __init +txx9_i8259_irq_setup(int irq) +{ + int err; + + init_i8259_irqs(); + err = request_irq(irq, &i8259_interrupt, IRQF_DISABLED|IRQF_SHARED, + "cascade(i8259)", (void *)(long)irq); + if (!err) + printk(KERN_INFO "PCI-ISA bridge PIC (irq %d)\n", irq); + return err; +} + +static void __init quirk_slc90e66_bridge(struct pci_dev *dev) +{ + int irq; /* PCI/ISA Bridge interrupt */ + u8 reg_64; + u32 reg_b0; + u8 reg_e1; + irq = pcibios_map_irq(dev, PCI_SLOT(dev->devfn), 1); /* INTA */ + if (!irq) + return; + txx9_i8259_irq_setup(irq); + pci_read_config_byte(dev, 0x64, ®_64); + pci_read_config_dword(dev, 0xb0, ®_b0); + pci_read_config_byte(dev, 0xe1, ®_e1); + /* serial irq control */ + reg_64 = 0xd0; + /* serial irq pin */ + reg_b0 |= 0x00010000; + /* ide irq on isa14 */ + reg_e1 &= 0xf0; + reg_e1 |= 0x0d; + pci_write_config_byte(dev, 0x64, reg_64); + pci_write_config_dword(dev, 0xb0, reg_b0); + pci_write_config_byte(dev, 0xe1, reg_e1); + + smsc_fdc37m81x_init(0x3f0); + smsc_fdc37m81x_config_beg(); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, + SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, + 1); + smsc_fdc37m81x_config_end(); +} + +static void quirk_slc90e66_ide(struct pci_dev *dev) +{ + unsigned char dat; + int regs[2] = {0x41, 0x43}; + int i; + + /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14); + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &dat); + printk(KERN_INFO "PCI: %s: IRQ %02x", pci_name(dev), dat); + /* enable SMSC SLC90E66 IDE */ + for (i = 0; i < ARRAY_SIZE(regs); i++) { + pci_read_config_byte(dev, regs[i], &dat); + pci_write_config_byte(dev, regs[i], dat | 0x80); + pci_read_config_byte(dev, regs[i], &dat); + printk(KERN_CONT " IDETIM%d %02x", i, dat); + } + pci_read_config_byte(dev, 0x5c, &dat); + /* + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + * + * This line of code is intended to provide the user with a work + * around solution to the anomalies cited in SMSC's anomaly sheet + * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". + * + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + */ + dat |= 0x01; + pci_write_config_byte(dev, regs[i], dat); + pci_read_config_byte(dev, 0x5c, &dat); + printk(KERN_CONT " REG5C %02x", dat); + printk(KERN_CONT "\n"); +} +#endif /* CONFIG_TOSHIBA_FPCIB0 */ + +static void final_fixup(struct pci_dev *dev) +{ + unsigned char bist; + + /* Do build-in self test */ + if (pci_read_config_byte(dev, PCI_BIST, &bist) == PCIBIOS_SUCCESSFUL && + (bist & PCI_BIST_CAPABLE)) { + unsigned long timeout; + pci_set_power_state(dev, PCI_D0); + printk(KERN_INFO "PCI: %s BIST...", pci_name(dev)); + pci_write_config_byte(dev, PCI_BIST, PCI_BIST_START); + timeout = jiffies + HZ * 2; /* timeout after 2 sec */ + do { + pci_read_config_byte(dev, PCI_BIST, &bist); + if (time_after(jiffies, timeout)) + break; + } while (bist & PCI_BIST_START); + if (bist & (PCI_BIST_CODE_MASK | PCI_BIST_START)) + printk(KERN_CONT "failed. (0x%x)\n", bist); + else + printk(KERN_CONT "OK.\n"); + } +} + +#ifdef CONFIG_TOSHIBA_FPCIB0 +#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0, + quirk_slc90e66_bridge); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, + quirk_slc90e66_ide); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, + quirk_slc90e66_ide); +#endif +DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup); +DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup); diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c new file mode 100644 index 000000000000..46a631177757 --- /dev/null +++ b/arch/mips/txx9/generic/setup.c @@ -0,0 +1,51 @@ +/* + * linux/arch/mips/txx9/generic/setup.c + * + * Based on linux/arch/mips/txx9/rbtx4938/setup.c, + * and RBTX49xx patch from CELF patch archive. + * + * 2003-2005 (c) MontaVista Software, Inc. + * (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/kernel.h> +#include <linux/types.h> +#include <asm/txx9/generic.h> + +/* EBUSC settings of TX4927, etc. */ +struct resource txx9_ce_res[8]; +static char txx9_ce_res_name[8][4]; /* "CEn" */ + +/* pcode, internal register */ +char txx9_pcode_str[8]; +static struct resource txx9_reg_res = { + .name = txx9_pcode_str, + .flags = IORESOURCE_MEM, +}; +void __init +txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) { + sprintf(txx9_ce_res_name[i], "CE%d", i); + txx9_ce_res[i].flags = IORESOURCE_MEM; + txx9_ce_res[i].name = txx9_ce_res_name[i]; + } + + sprintf(txx9_pcode_str, "TX%x", pcode); + if (base) { + txx9_reg_res.start = base & 0xfffffffffULL; + txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1); + request_resource(&iomem_resource, &txx9_reg_res); + } +} + +/* clocks */ +unsigned int txx9_master_clock; +unsigned int txx9_cpu_clock; +unsigned int txx9_gbus_clock; diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c index 85e1daf15c7b..b97d22e15da6 100644 --- a/arch/mips/txx9/jmr3927/irq.c +++ b/arch/mips/txx9/jmr3927/irq.c @@ -109,6 +109,7 @@ static struct irqaction ioc_action = { .name = "IOC", }; +#ifdef CONFIG_PCI static irqreturn_t jmr3927_pcierr_interrupt(int irq, void *dev_id) { printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); @@ -122,6 +123,7 @@ static struct irqaction pcierr_action = { .mask = CPU_MASK_NONE, .name = "PCI error", }; +#endif static void __init jmr3927_irq_init(void); diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 41e0f3b3af2c..baa8c8db9a94 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -30,7 +30,6 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> -#include <linux/pci.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/pm.h> @@ -44,6 +43,7 @@ #include <asm/txx9tmr.h> #include <asm/txx9pio.h> #include <asm/reboot.h> +#include <asm/txx9/pci.h> #include <asm/txx9/jmr3927.h> #include <asm/mipsregs.h> @@ -96,8 +96,6 @@ void __init plat_time_init(void) extern char * __init prom_getcmdline(void); static void jmr3927_board_init(void); -extern struct resource pci_io_resource; -extern struct resource pci_mem_resource; void __init plat_mem_setup(void) { @@ -112,8 +110,8 @@ void __init plat_mem_setup(void) /* * IO/MEM resources. */ - ioport_resource.start = pci_io_resource.start; - ioport_resource.end = pci_io_resource.end; + ioport_resource.start = 0; + ioport_resource.end = 0xffffffff; iomem_resource.start = 0; iomem_resource.end = 0xffffffff; @@ -191,9 +189,33 @@ void __init plat_mem_setup(void) static void tx3927_setup(void); +static void __init jmr3927_pci_setup(void) +{ +#ifdef CONFIG_PCI + int extarb = !(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB); + struct pci_controller *c; + + c = txx9_alloc_pci_controller(&txx9_primary_pcic, + JMR3927_PCIMEM, JMR3927_PCIMEM_SIZE, + JMR3927_PCIIO, JMR3927_PCIIO_SIZE); + register_pci_controller(c); + if (!extarb) { + /* Reset PCI Bus */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, + JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + } + tx3927_pcic_setup(c, JMR3927_SDRAM_SIZE, extarb); +#endif /* CONFIG_PCI */ +} + static void __init jmr3927_board_init(void) { tx3927_setup(); + jmr3927_pci_setup(); /* SIO0 DTR on */ jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR); @@ -210,14 +232,6 @@ static void __init jmr3927_board_init(void) static void __init tx3927_setup(void) { int i; -#ifdef CONFIG_PCI - unsigned long mips_pci_io_base = JMR3927_PCIIO; - unsigned long mips_pci_io_size = JMR3927_PCIIO_SIZE; - unsigned long mips_pci_mem_base = JMR3927_PCIMEM; - unsigned long mips_pci_mem_size = JMR3927_PCIMEM_SIZE; - /* for legacy I/O, PCI I/O PCI Bus address must be 0 */ - unsigned long mips_pci_io_pciaddr = 0; -#endif /* SDRAMC are configured by PROM */ @@ -272,74 +286,6 @@ static void __init tx3927_setup(void) tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE; #endif -#ifdef CONFIG_PCI - /* PCIC */ - printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:", - tx3927_pcicptr->did, tx3927_pcicptr->vid, - tx3927_pcicptr->rid); - if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) { - printk("External\n"); - /* XXX */ - } else { - printk("Internal\n"); - - /* Reset PCI Bus */ - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - udelay(100); - jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, - JMR3927_IOC_RESET_ADDR); - udelay(100); - jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); - - - /* 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 = ~(mips_pci_io_size - 1); - tx3927_pcicptr->ilbioma = mips_pci_io_base; - tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr; - tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1); - tx3927_pcicptr->ilbmma = mips_pci_mem_base; - tx3927_pcicptr->ipbmma = mips_pci_mem_base; - /* PCI->LB mappings */ - tx3927_pcicptr->iobas = 0xffffffff; - tx3927_pcicptr->ioba = 0; - tx3927_pcicptr->tlbioma = 0; - tx3927_pcicptr->mbas = ~(mips_pci_mem_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 */ - 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; - } -#endif /* CONFIG_PCI */ - /* PIO */ /* PIO[15:12] connected to LEDs */ __raw_writel(0x0000f000, &tx3927_pioptr->dir); diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c index 936e50e91d95..bef1447aeed2 100644 --- a/arch/mips/txx9/rbtx4927/irq.c +++ b/arch/mips/txx9/rbtx4927/irq.c @@ -111,9 +111,6 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #include <linux/types.h> #include <linux/interrupt.h> #include <asm/io.h> -#ifdef CONFIG_TOSHIBA_FPCIB0 -#include <asm/i8259.h> -#endif #include <asm/txx9/rbtx4927.h> #define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 @@ -125,8 +122,6 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC #define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) -extern int tx4927_using_backplane; - static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); @@ -146,17 +141,8 @@ int toshiba_rbtx4927_irq_nested(int sw_irq) u8 level3; level3 = readb(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; - if (level3) { + if (level3) sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + fls(level3) - 1; -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (sw_irq == TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC && - tx4927_using_backplane) { - int irq = i8259_irq(); - if (irq >= 0) - sw_irq = irq; - } -#endif - } return (sw_irq); } @@ -205,10 +191,6 @@ void __init arch_init_irq(void) tx4927_irq_init(); toshiba_rbtx4927_irq_ioc_init(); -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (tx4927_using_backplane) - init_i8259_irqs(); -#endif /* Onboard 10M Ether: High Active */ set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH); } diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index df1b6e99b666..86b870abc319 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -47,10 +47,10 @@ #include <linux/types.h> #include <linux/ioport.h> #include <linux/interrupt.h> -#include <linux/pci.h> #include <linux/pm.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/delay.h> #include <asm/bootinfo.h> #include <asm/io.h> @@ -58,10 +58,10 @@ #include <asm/reboot.h> #include <asm/time.h> #include <asm/txx9tmr.h> -#ifdef CONFIG_TOSHIBA_FPCIB0 -#include <asm/txx9/smsc_fdc37m81x.h> -#endif +#include <asm/txx9/generic.h> +#include <asm/txx9/pci.h> #include <asm/txx9/rbtx4927.h> +#include <asm/txx9/tx4938.h> /* for TX4937 */ #ifdef CONFIG_SERIAL_TXX9 #include <linux/serial_core.h> #endif @@ -70,356 +70,116 @@ extern void toshiba_rbtx4927_restart(char *command); extern void toshiba_rbtx4927_halt(void); extern void toshiba_rbtx4927_power_off(void); - -int tx4927_using_backplane = 0; - extern void toshiba_rbtx4927_irq_setup(void); char *prom_getcmdline(void); -#ifdef CONFIG_PCI -#undef TX4927_SUPPORT_COMMAND_IO -#undef TX4927_SUPPORT_PCI_66 -int tx4927_cpu_clock = 100000000; /* 100MHz */ -unsigned long mips_pci_io_base; -unsigned long mips_pci_io_size; -unsigned long mips_pci_mem_base; -unsigned long mips_pci_mem_size; -/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ -unsigned long mips_pci_io_pciaddr = 0; -unsigned long mips_memory_upper; static int tx4927_ccfg_toeon = 1; -static int tx4927_pcic_trdyto = 0; /* default: disabled */ -unsigned long tx4927_ce_base[8]; -int tx4927_pci66 = 0; /* 0:auto */ -#endif char *toshiba_name = ""; #ifdef CONFIG_PCI -extern struct pci_controller tx4927_controller; - -static struct pci_dev *fake_pci_dev(struct pci_controller *hose, - int top_bus, int busnr, int devfn) +static void __init tx4927_pci_setup(void) { - static struct pci_dev dev; - static struct pci_bus bus; - - dev.sysdata = (void *)hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - bus.parent = NULL; - dev.bus = &bus; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -static int early_##rw##_config_##size(struct pci_controller *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ + int extarb = !(__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB); + struct pci_controller *c = &txx9_primary_pcic; + + register_pci_controller(c); + + if (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66) + txx9_pci_option = + (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | + TXX9_PCI_OPT_CLK_66; /* already configured */ + + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_66) + tx4927_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + + tx4927_report_pciclk(); + tx4927_pcic_setup(tx4927_pcicptr, c, extarb); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_AUTO && + txx9_pci66_check(c, 0, 0)) { + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + tx4927_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + /* Reinitialize PCIC */ + tx4927_report_pciclk(); + tx4927_pcic_setup(tx4927_pcicptr, c, extarb); + } } -EARLY_PCI_OP(read, byte, u8 *) -EARLY_PCI_OP(read, dword, u32 *) -EARLY_PCI_OP(write, byte, u8) -EARLY_PCI_OP(write, dword, u32) - -static int __init tx4927_pcibios_init(void) +static void __init tx4937_pci_setup(void) { - unsigned int id; - u32 pci_devfn; - int devfn_start = 0; - int devfn_stop = 0xff; - int busno = 0; /* One bus on the Toshiba */ - struct pci_controller *hose = &tx4927_controller; - - for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { - early_read_config_dword(hose, busno, busno, pci_devfn, - PCI_VENDOR_ID, &id); - - if (id == 0xffffffff) { - continue; - } - - if (id == 0x94601055) { - u8 v08_64; - u32 v32_b0; - u8 v08_e1; - - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x64, &v08_64); - early_read_config_dword(hose, busno, busno, - pci_devfn, 0xb0, &v32_b0); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0xe1, &v08_e1); - - /* serial irq control */ - v08_64 = 0xd0; - - /* serial irq pin */ - v32_b0 |= 0x00010000; - - /* ide irq on isa14 */ - v08_e1 &= 0xf0; - v08_e1 |= 0x0d; - - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x64, v08_64); - early_write_config_dword(hose, busno, busno, - pci_devfn, 0xb0, v32_b0); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0xe1, v08_e1); - } - - if (id == 0x91301055) { - u8 v08_04; - u8 v08_09; - u8 v08_41; - u8 v08_43; - u8 v08_5c; - - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x04, &v08_04); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x09, &v08_09); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x41, &v08_41); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x43, &v08_43); - early_read_config_byte(hose, busno, busno, - pci_devfn, 0x5c, &v08_5c); - - /* enable ide master/io */ - v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); - - /* enable ide native mode */ - v08_09 |= 0x05; - - /* enable primary ide */ - v08_41 |= 0x80; - - /* enable secondary ide */ - v08_43 |= 0x80; - - /* - * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! - * - * This line of code is intended to provide the user with a work - * around solution to the anomalies cited in SMSC's anomaly sheet - * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". - * - * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! - */ - v08_5c |= 0x01; - - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x5c, v08_5c); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x04, v08_04); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x09, v08_09); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x41, v08_41); - early_write_config_byte(hose, busno, busno, - pci_devfn, 0x43, v08_43); - } - + int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB); + struct pci_controller *c = &txx9_primary_pcic; + + register_pci_controller(c); + + if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) + txx9_pci_option = + (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | + TXX9_PCI_OPT_CLK_66; /* already configured */ + + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_66) + tx4938_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + + tx4938_report_pciclk(); + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_AUTO && + txx9_pci66_check(c, 0, 0)) { + /* Reset PCI Bus */ + writeb(1, rbtx4927_pcireset_addr); + /* Reset PCIC */ + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + tx4938_pciclk66_setup(); + mdelay(10); + /* clear PCIC reset */ + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + writeb(0, rbtx4927_pcireset_addr); + iob(); + /* Reinitialize PCIC */ + tx4938_report_pciclk(); + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); } - - register_pci_controller(&tx4927_controller); - return 0; } -arch_initcall(tx4927_pcibios_init); - -extern struct resource pci_io_resource; -extern struct resource pci_mem_resource; - -void __init tx4927_pci_setup(void) +static int __init rbtx4927_arch_init(void) { - static int called = 0; - extern unsigned int tx4927_get_mem_size(void); - - mips_memory_upper = tx4927_get_mem_size() << 20; - mips_memory_upper += KSEG0; - mips_pci_io_base = TX4927_PCIIO; - mips_pci_io_size = TX4927_PCIIO_SIZE; - mips_pci_mem_base = TX4927_PCIMEM; - mips_pci_mem_size = TX4927_PCIMEM_SIZE; - - if (!called) { - printk - ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", - toshiba_name, - (unsigned short) (tx4927_pcicptr->pciid >> 16), - (unsigned short) (tx4927_pcicptr->pciid & 0xffff), - (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), - (!(tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIXARB)) ? "External" : - "Internal"); - called = 1; - } - printk("%s PCIC --%s PCICLK:", toshiba_name, - (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); - if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { - int pciclk = 0; - if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long) tx4927_ccfgptr-> - ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { - case TX4937_CCFG_PCIDIVMODE_4: - pciclk = tx4927_cpu_clock / 4; - break; - case TX4937_CCFG_PCIDIVMODE_4_5: - pciclk = tx4927_cpu_clock * 2 / 9; - break; - case TX4937_CCFG_PCIDIVMODE_5: - pciclk = tx4927_cpu_clock / 5; - break; - case TX4937_CCFG_PCIDIVMODE_5_5: - pciclk = tx4927_cpu_clock * 2 / 11; - break; - case TX4937_CCFG_PCIDIVMODE_8: - pciclk = tx4927_cpu_clock / 8; - break; - case TX4937_CCFG_PCIDIVMODE_9: - pciclk = tx4927_cpu_clock / 9; - break; - case TX4937_CCFG_PCIDIVMODE_10: - pciclk = tx4927_cpu_clock / 10; - break; - case TX4937_CCFG_PCIDIVMODE_11: - pciclk = tx4927_cpu_clock / 11; - break; - } - - else - switch ((unsigned long) tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { - case TX4927_CCFG_PCIDIVMODE_2_5: - pciclk = tx4927_cpu_clock * 2 / 5; - break; - case TX4927_CCFG_PCIDIVMODE_3: - pciclk = tx4927_cpu_clock / 3; - break; - case TX4927_CCFG_PCIDIVMODE_5: - pciclk = tx4927_cpu_clock / 5; - break; - case TX4927_CCFG_PCIDIVMODE_6: - pciclk = tx4927_cpu_clock / 6; - break; - } - - printk("Internal(%dMHz)", pciclk / 1000000); - } else - printk("External"); - printk("\n"); - - /* GB->PCI mappings */ - tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; - tx4927_pcicptr->g2piogbase = mips_pci_io_base | -#ifdef __BIG_ENDIAN - TX4927_PCIC_G2PIOGBASE_ECHG -#else - TX4927_PCIC_G2PIOGBASE_BSDIS -#endif - ; - - tx4927_pcicptr->g2piopbase = 0; - - tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4; - tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base | -#ifdef __BIG_ENDIAN - TX4927_PCIC_G2PMnGBASE_ECHG -#else - TX4927_PCIC_G2PMnGBASE_BSDIS -#endif - ; - tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base; - - tx4927_pcicptr->g2pmmask[1] = 0; - tx4927_pcicptr->g2pmgbase[1] = 0; - tx4927_pcicptr->g2pmpbase[1] = 0; - tx4927_pcicptr->g2pmmask[2] = 0; - tx4927_pcicptr->g2pmgbase[2] = 0; - tx4927_pcicptr->g2pmpbase[2] = 0; - - - /* PCI->GB mappings (I/O 256B) */ - tx4927_pcicptr->p2giopbase = 0; /* 256B */ - - /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */ - tx4927_pcicptr->p2gm0plbase = 0; - tx4927_pcicptr->p2gm0pubase = 0; - tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN | -#ifdef __BIG_ENDIAN - TX4927_PCIC_P2GMnGBASE_TECHG -#else - TX4927_PCIC_P2GMnGBASE_TBSDIS -#endif - ; - - /* PCI->GB mappings (MEM 16MB) -not used */ - tx4927_pcicptr->p2gm1plbase = 0xffffffff; - tx4927_pcicptr->p2gm1pubase = 0xffffffff; - tx4927_pcicptr->p2gmgbase[1] = 0; - - /* PCI->GB mappings (MEM 1MB) -not used */ - tx4927_pcicptr->p2gm2pbase = 0xffffffff; - tx4927_pcicptr->p2gmgbase[2] = 0; - - - /* Enable Initiator Memory 0 Space, I/O Space, Config */ - tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK; - tx4927_pcicptr->pciccfg |= - TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE | - TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR; - - - /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ - tx4927_pcicptr->pcicfg1 = 0; - - if (tx4927_pcic_trdyto >= 0) { - tx4927_pcicptr->g2ptocnt &= ~0xff; - tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff); - } - - /* Clear All Local Bus Status */ - tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL; - /* Enable All Local Bus Interrupts */ - tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL; - /* Clear All Initiator Status */ - tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL; - /* Enable All Initiator Interrupts */ - tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL; - /* Clear All PCI Status Error */ - tx4927_pcicptr->pcistatus = - (tx4927_pcicptr->pcistatus & 0x0000ffff) | - (TX4927_PCIC_PCISTATUS_ALL << 16); - /* Enable All PCI Status Error Interrupts */ - tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL; - - /* PCIC Int => IRC IRQ16 */ - tx4927_pcicptr->pcicfg2 = - (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC; - - if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) { - /* XXX */ - } else { - /* Reset Bus Arbiter */ - tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA; - /* Enable Bus Arbiter */ - tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN; - } - - tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + if (mips_machtype == MACH_TOSHIBA_RBTX4937) + tx4937_pci_setup(); + else + tx4927_pci_setup(); + return 0; } +arch_initcall(rbtx4927_arch_init); #endif /* CONFIG_PCI */ static void __noreturn wait_forever(void) @@ -479,8 +239,6 @@ void __init plat_mem_setup(void) cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); write_c0_config(cp0_config); - set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); - ioport_resource.end = 0xffffffff; iomem_resource.end = 0xffffffff; @@ -492,8 +250,13 @@ void __init plat_mem_setup(void) txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL); #ifdef CONFIG_PCI + txx9_alloc_pci_controller(&txx9_primary_pcic, + RBTX4927_PCIMEM, RBTX4927_PCIMEM_SIZE, + RBTX4927_PCIIO, RBTX4927_PCIIO_SIZE); +#else + set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); +#endif - /* PCIC */ /* * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. * @@ -517,58 +280,38 @@ void __init plat_mem_setup(void) * */ if (mips_machtype == MACH_TOSHIBA_RBTX4937) - switch ((unsigned long)tx4927_ccfgptr-> - ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { - case TX4937_CCFG_PCIDIVMODE_8: - case TX4937_CCFG_PCIDIVMODE_4: - tx4927_cpu_clock = 266666666; /* 266MHz */ + switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) & + TX4938_CCFG_PCIDIVMODE_MASK) { + case TX4938_CCFG_PCIDIVMODE_8: + case TX4938_CCFG_PCIDIVMODE_4: + txx9_cpu_clock = 266666666; /* 266MHz */ break; - case TX4937_CCFG_PCIDIVMODE_9: - case TX4937_CCFG_PCIDIVMODE_4_5: - tx4927_cpu_clock = 300000000; /* 300MHz */ + case TX4938_CCFG_PCIDIVMODE_9: + case TX4938_CCFG_PCIDIVMODE_4_5: + txx9_cpu_clock = 300000000; /* 300MHz */ break; default: - tx4927_cpu_clock = 333333333; /* 333MHz */ + txx9_cpu_clock = 333333333; /* 333MHz */ } else - switch ((unsigned long)tx4927_ccfgptr-> - ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) & + TX4927_CCFG_PCIDIVMODE_MASK) { case TX4927_CCFG_PCIDIVMODE_2_5: case TX4927_CCFG_PCIDIVMODE_5: - tx4927_cpu_clock = 166666666; /* 166MHz */ + txx9_cpu_clock = 166666666; /* 166MHz */ break; default: - tx4927_cpu_clock = 200000000; /* 200MHz */ + txx9_cpu_clock = 200000000; /* 200MHz */ } + /* change default value to udelay/mdelay take reasonable time */ + loops_per_jiffy = txx9_cpu_clock / HZ / 2; /* CCFG */ /* do reset on watchdog */ - tx4927_ccfgptr->ccfg |= TX4927_CCFG_WR; + tx4927_ccfg_set(TX4927_CCFG_WR); /* enable Timeout BusError */ if (tx4927_ccfg_toeon) - tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; - - tx4927_pci_setup(); - if (tx4927_using_backplane == 1) - printk("backplane board IS installed\n"); - else - printk("No Backplane \n"); - - /* this is on ISA bus behind PCI bus, so need PCI up first */ -#ifdef CONFIG_TOSHIBA_FPCIB0 - if (tx4927_using_backplane) { - smsc_fdc37m81x_init(0x3f0); - smsc_fdc37m81x_config_beg(); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, - SMSC_FDC37M81X_KBD); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); - smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, - 1); - smsc_fdc37m81x_config_end(); - } -#endif -#endif /* CONFIG_PCI */ + tx4927_ccfg_set(TX4927_CCFG_TOE); #ifdef CONFIG_SERIAL_TXX9 { @@ -611,8 +354,8 @@ void __init plat_mem_setup(void) void __init plat_time_init(void) { - mips_hpt_frequency = tx4927_cpu_clock / 2; - if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS) + mips_hpt_frequency = txx9_cpu_clock / 2; + if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS) txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL, TXX9_IRQ_BASE + 17, 50000000); diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index bbd572c9675b..144d2cada820 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -15,7 +15,6 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/console.h> -#include <linux/pci.h> #include <linux/pm.h> #include <linux/platform_device.h> #include <linux/clk.h> @@ -26,6 +25,8 @@ #include <asm/txx9tmr.h> #include <asm/io.h> #include <asm/bootinfo.h> +#include <asm/txx9/generic.h> +#include <asm/txx9/pci.h> #include <asm/txx9/rbtx4938.h> #ifdef CONFIG_SERIAL_TXX9 #include <linux/serial_core.h> @@ -35,37 +36,13 @@ #include <asm/txx9pio.h> extern char * __init prom_getcmdline(void); -static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr); - /* These functions are used for rebooting or halting the machine*/ extern void rbtx4938_machine_restart(char *command); extern void rbtx4938_machine_halt(void); extern void rbtx4938_machine_power_off(void); -/* clocks */ -unsigned int txx9_master_clock; -unsigned int txx9_cpu_clock; -unsigned int txx9_gbus_clock; - -unsigned long rbtx4938_ce_base[8]; -unsigned long rbtx4938_ce_size[8]; -int txboard_pci66_mode; -static int tx4938_pcic_trdyto; /* default: disabled */ -static int tx4938_pcic_retryto; /* default: disabled */ static int tx4938_ccfg_toeon = 1; -struct tx4938_pcic_reg *pcicptrs[4] = { - tx4938_pcicptr /* default setting for TX4938 */ -}; - -static struct { - unsigned long base; - unsigned long size; -} phys_regions[16] __initdata; -static int num_phys_regions __initdata; - -#define PHYS_REGION_MINSIZE 0x10000 - void rbtx4938_machine_halt(void) { printk(KERN_NOTICE "System Halted\n"); @@ -95,473 +72,72 @@ void rbtx4938_machine_restart(char *command) ; } -void __init -txboard_add_phys_region(unsigned long base, unsigned long size) -{ - if (num_phys_regions >= ARRAY_SIZE(phys_regions)) { - printk("phys_region overflow\n"); - return; - } - phys_regions[num_phys_regions].base = base; - phys_regions[num_phys_regions].size = size; - num_phys_regions++; -} -unsigned long __init -txboard_find_free_phys_region(unsigned long begin, unsigned long end, - unsigned long size) -{ - unsigned long base; - int i; - - for (base = begin / size * size; base < end; base += size) { - for (i = 0; i < num_phys_regions; i++) { - if (phys_regions[i].size && - base <= phys_regions[i].base + (phys_regions[i].size - 1) && - base + (size - 1) >= phys_regions[i].base) - break; - } - if (i == num_phys_regions) - return base; - } - return 0; -} -unsigned long __init -txboard_find_free_phys_region_shrink(unsigned long begin, unsigned long end, - unsigned long *size) -{ - unsigned long sz, base; - for (sz = *size; sz >= PHYS_REGION_MINSIZE; sz /= 2) { - base = txboard_find_free_phys_region(begin, end, sz); - if (base) { - *size = sz; - return base; - } - } - return 0; -} -unsigned long __init -txboard_request_phys_region_range(unsigned long begin, unsigned long end, - unsigned long size) -{ - unsigned long base; - base = txboard_find_free_phys_region(begin, end, size); - if (base) - txboard_add_phys_region(base, size); - return base; -} -unsigned long __init -txboard_request_phys_region(unsigned long size) +static void __init rbtx4938_pci_setup(void) { - unsigned long base; - unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ - base = txboard_find_free_phys_region(begin, end, size); - if (base) - txboard_add_phys_region(base, size); - return base; -} -unsigned long __init -txboard_request_phys_region_shrink(unsigned long *size) -{ - unsigned long base; - unsigned long begin = 0, end = 0x20000000; /* search low 512MB */ - base = txboard_find_free_phys_region_shrink(begin, end, size); - if (base) - txboard_add_phys_region(base, *size); - return base; -} - #ifdef CONFIG_PCI -void __init -tx4938_pcic_setup(struct tx4938_pcic_reg *pcicptr, - struct pci_controller *channel, - unsigned long pci_io_base, - int extarb) -{ - int i; + int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB); + struct pci_controller *c = &txx9_primary_pcic; - /* Disable All Initiator Space */ - pcicptr->pciccfg &= ~(TX4938_PCIC_PCICCFG_G2PMEN(0)| - TX4938_PCIC_PCICCFG_G2PMEN(1)| - TX4938_PCIC_PCICCFG_G2PMEN(2)| - TX4938_PCIC_PCICCFG_G2PIOEN); - - /* GB->PCI mappings */ - pcicptr->g2piomask = (channel->io_resource->end - channel->io_resource->start) >> 4; - pcicptr->g2piogbase = pci_io_base | -#ifdef __BIG_ENDIAN - TX4938_PCIC_G2PIOGBASE_ECHG -#else - TX4938_PCIC_G2PIOGBASE_BSDIS -#endif - ; - pcicptr->g2piopbase = 0; - for (i = 0; i < 3; i++) { - pcicptr->g2pmmask[i] = 0; - pcicptr->g2pmgbase[i] = 0; - pcicptr->g2pmpbase[i] = 0; - } - if (channel->mem_resource->end) { - pcicptr->g2pmmask[0] = (channel->mem_resource->end - channel->mem_resource->start) >> 4; - pcicptr->g2pmgbase[0] = channel->mem_resource->start | -#ifdef __BIG_ENDIAN - TX4938_PCIC_G2PMnGBASE_ECHG -#else - TX4938_PCIC_G2PMnGBASE_BSDIS -#endif - ; - pcicptr->g2pmpbase[0] = channel->mem_resource->start; - } - /* PCI->GB mappings (I/O 256B) */ - pcicptr->p2giopbase = 0; /* 256B */ - pcicptr->p2giogbase = 0; - /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */ - pcicptr->p2gm0plbase = 0; - pcicptr->p2gm0pubase = 0; - pcicptr->p2gmgbase[0] = 0 | - TX4938_PCIC_P2GMnGBASE_TMEMEN | -#ifdef __BIG_ENDIAN - TX4938_PCIC_P2GMnGBASE_TECHG -#else - TX4938_PCIC_P2GMnGBASE_TBSDIS -#endif - ; - /* PCI->GB mappings (MEM 16MB) */ - pcicptr->p2gm1plbase = 0xffffffff; - pcicptr->p2gm1pubase = 0xffffffff; - pcicptr->p2gmgbase[1] = 0; - /* PCI->GB mappings (MEM 1MB) */ - pcicptr->p2gm2pbase = 0xffffffff; /* 1MB */ - pcicptr->p2gmgbase[2] = 0; - - pcicptr->pciccfg &= TX4938_PCIC_PCICCFG_GBWC_MASK; - /* Enable Initiator Memory Space */ - if (channel->mem_resource->end) - pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PMEN(0); - /* Enable Initiator I/O Space */ - if (channel->io_resource->end) - pcicptr->pciccfg |= TX4938_PCIC_PCICCFG_G2PIOEN; - /* Enable Initiator Config */ - pcicptr->pciccfg |= - TX4938_PCIC_PCICCFG_ICAEN | - TX4938_PCIC_PCICCFG_TCAR; - - /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ - pcicptr->pcicfg1 = 0; - - pcicptr->g2ptocnt &= ~0xffff; - - if (tx4938_pcic_trdyto >= 0) { - pcicptr->g2ptocnt &= ~0xff; - pcicptr->g2ptocnt |= (tx4938_pcic_trdyto & 0xff); - } - - if (tx4938_pcic_retryto >= 0) { - pcicptr->g2ptocnt &= ~0xff00; - pcicptr->g2ptocnt |= ((tx4938_pcic_retryto<<8) & 0xff00); - } - - /* Clear All Local Bus Status */ - pcicptr->pcicstatus = TX4938_PCIC_PCICSTATUS_ALL; - /* Enable All Local Bus Interrupts */ - pcicptr->pcicmask = TX4938_PCIC_PCICSTATUS_ALL; - /* Clear All Initiator Status */ - pcicptr->g2pstatus = TX4938_PCIC_G2PSTATUS_ALL; - /* Enable All Initiator Interrupts */ - pcicptr->g2pmask = TX4938_PCIC_G2PSTATUS_ALL; - /* Clear All PCI Status Error */ - pcicptr->pcistatus = - (pcicptr->pcistatus & 0x0000ffff) | - (TX4938_PCIC_PCISTATUS_ALL << 16); - /* Enable All PCI Status Error Interrupts */ - pcicptr->pcimask = TX4938_PCIC_PCISTATUS_ALL; - - if (!extarb) { - /* Reset Bus Arbiter */ - pcicptr->pbacfg = TX4938_PCIC_PBACFG_RPBA; - pcicptr->pbabm = 0; - /* Enable Bus Arbiter */ - pcicptr->pbacfg = TX4938_PCIC_PBACFG_PBAEN; - } - - /* PCIC Int => IRC IRQ16 */ - pcicptr->pcicfg2 = - (pcicptr->pcicfg2 & 0xffffff00) | TX4938_IR_PCIC; - - pcicptr->pcistatus = PCI_COMMAND_MASTER | - PCI_COMMAND_MEMORY | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; -} - -int __init -tx4938_report_pciclk(void) -{ - unsigned long pcode = TX4938_REV_PCODE(); - int pciclk = 0; - printk("TX%lx PCIC --%s PCICLK:", - pcode, - (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) ? " PCI66" : ""); - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { - - switch ((unsigned long)tx4938_ccfgptr->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(%dMHz)", pciclk / 1000000); - } else { - printk("External"); - pciclk = -1; - } - printk("\n"); - return pciclk; -} - -void __init set_tx4938_pcicptr(int ch, struct tx4938_pcic_reg *pcicptr) -{ - pcicptrs[ch] = pcicptr; -} - -struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch) -{ - return pcicptrs[ch]; -} - -static struct pci_dev *fake_pci_dev(struct pci_controller *hose, - int top_bus, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; + register_pci_controller(c); - dev.sysdata = bus.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - bus.parent = NULL; - dev.bus = &bus; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -static int early_##rw##_config_##size(struct pci_controller *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, word, u16 *) - -int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bus) -{ - u32 pci_devfn; - unsigned short vid; - int devfn_start = 0; - int devfn_stop = 0xff; - int cap66 = -1; - u16 stat; - - printk("PCI: Checking 66MHz capabilities...\n"); - - for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { - if (early_read_config_word(hose, top_bus, current_bus, - pci_devfn, PCI_VENDOR_ID, - &vid) != PCIBIOS_SUCCESSFUL) - continue; - - if (vid == 0xffff) continue; - - /* check 66MHz capability */ - if (cap66 < 0) - cap66 = 1; - if (cap66) { - early_read_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_STATUS, &stat); - if (!(stat & PCI_STATUS_66MHZ)) { - printk(KERN_DEBUG "PCI: %02x:%02x not 66MHz capable.\n", - current_bus, pci_devfn); - cap66 = 0; - break; - } - } - } - return cap66 > 0; -} - -int __init -tx4938_pciclk66_setup(void) -{ - int pciclk; - - /* Assert M66EN */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66; - /* Double PCICLK (if possible) */ - if (tx4938_ccfgptr->pcfg & TX4938_PCFG_PCICLKEN_ALL) { - unsigned int pcidivmode = - tx4938_ccfgptr->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_ccfgptr->ccfg = - (tx4938_ccfgptr->ccfg & ~TX4938_CCFG_PCIDIVMODE_MASK) - | pcidivmode; - printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n", - (unsigned long)tx4938_ccfgptr->ccfg); - } else { - pciclk = -1; - } - return pciclk; -} - -extern struct pci_controller tx4938_pci_controller[]; -static int __init tx4938_pcibios_init(void) -{ - unsigned long mem_base[2]; - unsigned long mem_size[2] = {TX4938_PCIMEM_SIZE_0, TX4938_PCIMEM_SIZE_1}; /* MAX 128M,64K */ - unsigned long io_base[2]; - unsigned long io_size[2] = {TX4938_PCIIO_SIZE_0, TX4938_PCIIO_SIZE_1}; /* MAX 16M,64K */ - /* TX4938 PCIC1: 64K MEM/IO is enough for ETH0,ETH1 */ - int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB); - - PCIBIOS_MIN_IO = 0x00001000UL; - - mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]); - io_base[0] = txboard_request_phys_region_shrink(&io_size[0]); - - printk("TX4938 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", - (unsigned short)(tx4938_pcicptr->pciid >> 16), - (unsigned short)(tx4938_pcicptr->pciid & 0xffff), - (unsigned short)(tx4938_pcicptr->pciccrev & 0xff), - extarb ? "External" : "Internal"); - - /* setup PCI area */ - tx4938_pci_controller[0].io_resource->start = io_base[0]; - tx4938_pci_controller[0].io_resource->end = (io_base[0] + io_size[0]) - 1; - tx4938_pci_controller[0].mem_resource->start = mem_base[0]; - tx4938_pci_controller[0].mem_resource->end = mem_base[0] + mem_size[0] - 1; - - set_tx4938_pcicptr(0, tx4938_pcicptr); - - register_pci_controller(&tx4938_pci_controller[0]); - - if (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI66) { - printk("TX4938_CCFG_PCI66 already configured\n"); - txboard_pci66_mode = -1; /* already configured */ - } + if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) + txx9_pci_option = + (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) | + TXX9_PCI_OPT_CLK_66; /* already configured */ /* Reset PCI Bus */ writeb(0, rbtx4938_pcireset_addr); /* Reset PCIC */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; - if (txboard_pci66_mode > 0) + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_66) tx4938_pciclk66_setup(); mdelay(10); /* clear PCIC reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); writeb(1, rbtx4938_pcireset_addr); - mmiowb(); - tx4938_report_pcic_status1(tx4938_pcicptr); + iob(); tx4938_report_pciclk(); - tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); - if (txboard_pci66_mode == 0 && - txboard_pci66_check(&tx4938_pci_controller[0], 0, 0)) { + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); + if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) == + TXX9_PCI_OPT_CLK_AUTO && + txx9_pci66_check(c, 0, 0)) { /* Reset PCI Bus */ writeb(0, rbtx4938_pcireset_addr); /* Reset PCIC */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIRST; + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); tx4938_pciclk66_setup(); mdelay(10); /* clear PCIC reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIRST; + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST); writeb(1, rbtx4938_pcireset_addr); - mmiowb(); + iob(); /* Reinitialize PCIC */ tx4938_report_pciclk(); - tx4938_pcic_setup(tx4938_pcicptr, &tx4938_pci_controller[0], io_base[0], extarb); + tx4927_pcic_setup(tx4938_pcicptr, c, extarb); } - mem_base[1] = txboard_request_phys_region_shrink(&mem_size[1]); - io_base[1] = txboard_request_phys_region_shrink(&io_size[1]); - /* Reset PCIC1 */ - tx4938_ccfgptr->clkctr |= TX4938_CLKCTR_PCIC1RST; - /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ - if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD)) - tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI1_66; - else - tx4938_ccfgptr->ccfg &= ~TX4938_CCFG_PCI1_66; - mdelay(10); - /* clear PCIC1 reset */ - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; - tx4938_report_pcic_status1(tx4938_pcic1ptr); - - printk("TX4938 PCIC1 -- DID:%04x VID:%04x RID:%02x", - (unsigned short)(tx4938_pcic1ptr->pciid >> 16), - (unsigned short)(tx4938_pcic1ptr->pciid & 0xffff), - (unsigned short)(tx4938_pcic1ptr->pciccrev & 0xff)); - printk("%s PCICLK:%dMHz\n", - (tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1_66) ? " PCI66" : "", - txx9_gbus_clock / - ((tx4938_ccfgptr->ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2) / - 1000000); - - /* assumption: CPHYSADDR(mips_io_port_base) == io_base[0] */ - tx4938_pci_controller[1].io_resource->start = - io_base[1] - io_base[0]; - tx4938_pci_controller[1].io_resource->end = - io_base[1] - io_base[0] + io_size[1] - 1; - tx4938_pci_controller[1].mem_resource->start = mem_base[1]; - tx4938_pci_controller[1].mem_resource->end = - mem_base[1] + mem_size[1] - 1; - set_tx4938_pcicptr(1, tx4938_pcic1ptr); - - register_pci_controller(&tx4938_pci_controller[1]); - - tx4938_pcic_setup(tx4938_pcic1ptr, &tx4938_pci_controller[1], io_base[1], extarb); - - /* map ioport 0 to PCI I/O space address 0 */ - set_io_port_base(KSEG1 + io_base[0]); - - return 0; -} - -arch_initcall(tx4938_pcibios_init); - + if (__raw_readq(&tx4938_ccfgptr->pcfg) & + (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL)) { + /* Reset PCIC1 */ + txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); + /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */ + if (!(__raw_readq(&tx4938_ccfgptr->ccfg) + & TX4938_CCFG_PCI1DMD)) + tx4938_ccfg_set(TX4938_CCFG_PCI1_66); + mdelay(10); + /* clear PCIC1 reset */ + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); + tx4938_report_pci1clk(); + + /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */ + c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000); + register_pci_controller(c); + tx4927_pcic_setup(tx4938_pcic1ptr, c, 0); + } #endif /* CONFIG_PCI */ +} /* SPI support */ @@ -594,7 +170,7 @@ static int __init rbtx4938_ethaddr_init(void) unsigned int id = TXX9_IRQ_BASE + (i ? TX4938_IR_ETH1 : TX4938_IR_ETH0); struct platform_device *pdev; - if (!(tx4938_ccfgptr->pcfg & + if (!(__raw_readq(&tx4938_ccfgptr->pcfg) & (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL))) continue; pdev = platform_device_alloc("tc35815-mac", id); @@ -611,18 +187,12 @@ device_initcall(rbtx4938_ethaddr_init); static void __init rbtx4938_spi_setup(void) { /* set SPI_SEL */ - tx4938_ccfgptr->pcfg |= TX4938_PCFG_SPI_SEL; + txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_SPI_SEL); } static struct resource rbtx4938_fpga_resource; - -static char pcode_str[8]; -static struct resource tx4938_reg_resource = { - .start = TX4938_REG_BASE, - .end = TX4938_REG_BASE + TX4938_REG_SIZE, - .name = pcode_str, - .flags = IORESOURCE_MEM -}; +static struct resource tx4938_sdram_resource[4]; +static struct resource tx4938_sram_resource; void __init tx4938_board_setup(void) { @@ -631,24 +201,28 @@ void __init tx4938_board_setup(void) int cpuclk = 0; unsigned long pcode = TX4938_REV_PCODE(); - ioport_resource.start = 0x1000; + ioport_resource.start = 0; ioport_resource.end = 0xffffffff; - iomem_resource.start = 0x1000; + iomem_resource.start = 0; iomem_resource.end = 0xffffffff; /* expand to 4GB */ - sprintf(pcode_str, "TX%lx", pcode); + txx9_reg_res_init(pcode, TX4938_REG_BASE, + TX4938_REG_SIZE); /* SDRAMC,EBUSC are configured by PROM */ for (i = 0; i < 8; i++) { - if (!(tx4938_ebuscptr->cr[i] & 0x8)) + if (!(TX4938_EBUSC_CR(i) & 0x8)) continue; /* disabled */ - rbtx4938_ce_base[i] = (unsigned long)TX4938_EBUSC_BA(i); - txboard_add_phys_region(rbtx4938_ce_base[i], TX4938_EBUSC_SIZE(i)); + txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i); + txx9_ce_res[i].end = + txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1; + request_resource(&iomem_resource, &txx9_ce_res[i]); } /* clocks */ if (txx9_master_clock) { + u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); /* calculate gbus_clock and cpu_clock_freq from master_clock */ - divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; + divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; switch (divmode) { case TX4938_CCFG_DIVMODE_8: case TX4938_CCFG_DIVMODE_10: @@ -678,12 +252,13 @@ void __init tx4938_board_setup(void) } txx9_cpu_clock = cpuclk; } else { + u64 ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg); if (txx9_cpu_clock == 0) { txx9_cpu_clock = 300000000; /* 300MHz */ } /* calculate gbus_clock and master_clock from cpu_clock_freq */ cpuclk = txx9_cpu_clock; - divmode = (unsigned long)tx4938_ccfgptr->ccfg & TX4938_CCFG_DIVMODE_MASK; + divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK; switch (divmode) { case TX4938_CCFG_DIVMODE_2: case TX4938_CCFG_DIVMODE_8: @@ -717,32 +292,32 @@ void __init tx4938_board_setup(void) /* CCFG */ /* clear WatchDogReset,BusErrorOnWrite flag (W1C) */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_WDRST | TX4938_CCFG_BEOW; + tx4938_ccfg_set(TX4938_CCFG_WDRST | TX4938_CCFG_BEOW); /* do reset on watchdog */ - tx4938_ccfgptr->ccfg |= TX4938_CCFG_WR; + tx4938_ccfg_set(TX4938_CCFG_WR); /* clear PCIC1 reset */ - if (tx4938_ccfgptr->clkctr & TX4938_CLKCTR_PCIC1RST) - tx4938_ccfgptr->clkctr &= ~TX4938_CLKCTR_PCIC1RST; + txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST); /* enable Timeout BusError */ if (tx4938_ccfg_toeon) - tx4938_ccfgptr->ccfg |= TX4938_CCFG_TOE; + tx4938_ccfg_set(TX4938_CCFG_TOE); /* DMA selection */ - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_DMASEL_ALL; + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL); /* Use external clock for external arbiter */ - if (!(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB)) - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_PCICLKEN_ALL; - - printk("%s -- %dMHz(M%dMHz) CRIR:%08lx CCFG:%Lx PCFG:%Lx\n", - pcode_str, - cpuclk / 1000000, txx9_master_clock / 1000000, - (unsigned long)tx4938_ccfgptr->crir, - tx4938_ccfgptr->ccfg, - tx4938_ccfgptr->pcfg); - - printk("%s SDRAMC --", pcode_str); + if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB)) + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL); + + printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n", + txx9_pcode_str, + (cpuclk + 500000) / 1000000, + (txx9_master_clock + 500000) / 1000000, + (__u32)____raw_readq(&tx4938_ccfgptr->crir), + (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg), + (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg)); + + printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str); for (i = 0; i < 4; i++) { unsigned long long cr = tx4938_sdramcptr->cr[i]; unsigned long ram_base, ram_size; @@ -753,16 +328,24 @@ void __init tx4938_board_setup(void) if (ram_base >= 0x20000000) continue; /* high memory (ignore) */ printk(" CR%d:%016Lx", i, cr); - txboard_add_phys_region(ram_base, ram_size); + tx4938_sdram_resource[i].name = "SDRAM"; + tx4938_sdram_resource[i].start = ram_base; + tx4938_sdram_resource[i].end = ram_base + ram_size - 1; + tx4938_sdram_resource[i].flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4938_sdram_resource[i]); } printk(" TR:%09Lx\n", tx4938_sdramcptr->tr); /* SRAM */ - if (pcode == 0x4938 && tx4938_sramcptr->cr & 1) { + if (tx4938_sramcptr->cr & 1) { unsigned int size = 0x800; unsigned long base = (tx4938_sramcptr->cr >> (39-11)) & ~(size - 1); - txboard_add_phys_region(base, size); + tx4938_sram_resource.name = "SRAM"; + tx4938_sram_resource.start = base; + tx4938_sram_resource.end = base + size - 1; + tx4938_sram_resource.flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &tx4938_sram_resource); } /* TMR */ @@ -778,71 +361,15 @@ void __init tx4938_board_setup(void) __raw_writel(0, &tx4938_pioptr->maskcpu); __raw_writel(0, &tx4938_pioptr->maskext); - /* TX4938 internal registers */ - if (request_resource(&iomem_resource, &tx4938_reg_resource)) - printk("request resource for internal registers failed\n"); -} - #ifdef CONFIG_PCI -static inline void tx4938_report_pcic_status1(struct tx4938_pcic_reg *pcicptr) -{ - unsigned short pcistatus = (unsigned short)(pcicptr->pcistatus >> 16); - unsigned long g2pstatus = pcicptr->g2pstatus; - unsigned long pcicstatus = pcicptr->pcicstatus; - static struct { - unsigned long 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[] = { - { TX4938_PCIC_G2PSTATUS_TTOE, "TIOE" }, - { TX4938_PCIC_G2PSTATUS_RTOE, "RTOE" }, - }, pcicstat_tbl[] = { - { TX4938_PCIC_PCICSTATUS_PME, "PME" }, - { TX4938_PCIC_PCICSTATUS_TLB, "TLB" }, - { TX4938_PCIC_PCICSTATUS_NIB, "NIB" }, - { TX4938_PCIC_PCICSTATUS_ZIB, "ZIB" }, - { TX4938_PCIC_PCICSTATUS_PERR, "PERR" }, - { TX4938_PCIC_PCICSTATUS_SERR, "SERR" }, - { TX4938_PCIC_PCICSTATUS_GBE, "GBE" }, - { TX4938_PCIC_PCICSTATUS_IWB, "IWB" }, - }; - int i; - - printk("pcistat:%04x(", pcistatus); - for (i = 0; i < ARRAY_SIZE(pcistat_tbl); i++) - if (pcistatus & pcistat_tbl[i].flag) - printk("%s ", pcistat_tbl[i].str); - printk("), g2pstatus:%08lx(", g2pstatus); - for (i = 0; i < ARRAY_SIZE(g2pstat_tbl); i++) - if (g2pstatus & g2pstat_tbl[i].flag) - printk("%s ", g2pstat_tbl[i].str); - printk("), pcicstatus:%08lx(", pcicstatus); - for (i = 0; i < ARRAY_SIZE(pcicstat_tbl); i++) - if (pcicstatus & pcicstat_tbl[i].flag) - printk("%s ", pcicstat_tbl[i].str); - printk(")\n"); -} - -void tx4938_report_pcic_status(void) -{ - int i; - struct tx4938_pcic_reg *pcicptr; - for (i = 0; (pcicptr = get_tx4938_pcicptr(i)) != NULL; i++) - tx4938_report_pcic_status1(pcicptr); + txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0); +#endif } -#endif /* CONFIG_PCI */ - void __init plat_time_init(void) { mips_hpt_frequency = txx9_cpu_clock / 2; - if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS) + if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS) txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL, TXX9_IRQ_BASE + TX4938_IR_TMR(0), txx9_gbus_clock / 2); @@ -890,19 +417,20 @@ void __init plat_mem_setup(void) #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61 printk("PIOSEL: disabling both ata and nand selection\n"); local_irq_disable(); - tx4938_ccfgptr->pcfg &= ~(TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); + txx9_clear64(&tx4938_ccfgptr->pcfg, + TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL); #endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND printk("PIOSEL: enabling nand selection\n"); - tx4938_ccfgptr->pcfg |= TX4938_PCFG_NDF_SEL; - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_ATA_SEL; + txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); #endif #ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA printk("PIOSEL: enabling ata selection\n"); - tx4938_ccfgptr->pcfg |= TX4938_PCFG_ATA_SEL; - tx4938_ccfgptr->pcfg &= ~TX4938_PCFG_NDF_SEL; + txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL); + txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL); #endif #ifdef CONFIG_IP_PNP @@ -920,7 +448,7 @@ void __init plat_mem_setup(void) #endif rbtx4938_spi_setup(); - pcfg = tx4938_ccfgptr->pcfg; /* updated */ + pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */ /* fixup piosel */ if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) == TX4938_PCFG_ATA_SEL) @@ -1063,6 +591,7 @@ static int __init rbtx4938_arch_init(void) { txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, 16); gpiochip_add(&rbtx4938_spi_gpio_chip); + rbtx4938_pci_setup(); return rbtx4938_spi_init(); } arch_initcall(rbtx4938_arch_init); |