diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-07-25 22:45:45 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 19:31:57 +0100 |
commit | 23fbee9dd5d2a41d36af49ff8e1669fb0c29fda8 (patch) | |
tree | 4e24699269b9d4d2655d961e7a0ffb29931e9b2d | |
parent | 132940401174ed04f9e8f1ae2dad6f47da26ee0a (diff) |
Support for Toshiba's RBHMA4500 eval board for the TX4938.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
24 files changed, 4118 insertions, 0 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 338c21f3efd..1f53fe8a89f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -695,6 +695,24 @@ config SOC_AU1500 config SOC_AU1550 bool "SOC_AU1550" +config TOSHIBA_RBTX4938 + bool "Support for Toshiba RBTX4938 board" + select HAVE_STD_PC_SERIAL_PORT + select DMA_NONCOHERENT + select GENERIC_ISA_DMA + select HAS_TXX9_SERIAL + select HW_HAS_PCI + select I8259 + select ISA + select SWAP_IO_SPACE + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_BIG_ENDIAN + select TOSHIBA_BOARDS + help + This Toshiba board is based on the TX4938 processor. Say Y here to + support this machine type + endchoice choice @@ -837,6 +855,7 @@ config TOSHIBA_FPCIB0 source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" +source "arch/mips/tx4938/Kconfig" source "arch/mips/philips/pnx8550/common/Kconfig" config RWSEM_GENERIC_SPINLOCK diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9c91e70d8ee..3dc2fb81fb2 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -690,6 +690,13 @@ core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/ core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/ load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000 +# +# Toshiba RBTX4938 board +# +core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/toshiba_rbtx4938/ +core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/tx4938/common/ +load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000 + cflags-y += -Iinclude/asm-mips/mach-generic drivers-$(CONFIG_PCI) += arch/mips/pci/ diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index ea8438b81fe..6956de95a7e 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -52,5 +52,6 @@ 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-tx4938.o ops-tx4938.o obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o diff --git a/arch/mips/pci/fixup-tx4938.c b/arch/mips/pci/fixup-tx4938.c new file mode 100644 index 00000000000..f455520ada8 --- /dev/null +++ b/arch/mips/pci/fixup-tx4938.c @@ -0,0 +1,92 @@ +/* + * Toshiba rbtx4938 pci routines + * 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/tx4938/rbtx4938.h> + +extern struct pci_controller tx4938_pci_controller[]; + +int pci_get_irq(struct pci_dev *dev, int 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; + } + + /* IRQ rotation */ + irq--; /* 0-3 */ + if (dev->bus->parent == NULL && + (slot == TX4938_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; + } + irq++; /* 1-4 */ + + switch (irq) { + case 1: + irq = RBTX4938_IRQ_IOC_PCIA; + break; + case 2: + irq = RBTX4938_IRQ_IOC_PCIB; + break; + case 3: + irq = RBTX4938_IRQ_IOC_PCIC; + break; + case 4: + irq = RBTX4938_IRQ_IOC_PCID; + break; + } + return irq; +} + +int __init pcibios_map_irq(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 + */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} + diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c new file mode 100644 index 00000000000..4c0dcfce529 --- /dev/null +++ b/arch/mips/pci/ops-tx4938.c @@ -0,0 +1,198 @@ +/* + * 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/tx4938/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, int *flagsp) +{ + if (bus > 0) { + /* Type 1 configuration */ + tx4938_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 */ + tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc); + } + /* clear M_ABORT and Disable M_ABORT Int. */ + tx4938_pcicptr->pcistatus = + (tx4938_pcicptr->pcistatus & 0x0000ffff) | + (PCI_STATUS_REC_MASTER_ABORT << 16); + tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; + + return 0; +} + +static int check_abort(int flags) +{ + int code = PCIBIOS_SUCCESSFUL; + /* wait write cycle completion before checking error status */ + while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB) + ; + if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { + tx4938_pcicptr->pcistatus = + (tx4938_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; + code = PCIBIOS_DEVICE_NOT_FOUND; + } + return code; +} + +static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + int flags, retval, dev, busno, func; + + 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, &flags)) + return -1; + + switch (size) { + case 1: + *val = *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata | +#ifdef __BIG_ENDIAN + ((where & 3) ^ 3)); +#else + (where & 3)); +#endif + break; + case 2: + *val = *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata | +#ifdef __BIG_ENDIAN + ((where & 3) ^ 2)); +#else + (where & 3)); +#endif + break; + case 4: + *val = tx4938_pcicptr->g2pcfgdata; + break; + } + + retval = check_abort(flags); + 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 flags, dev, busno, func; + + 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, &flags)) + return -1; + + switch (size) { + case 1: + *(volatile u8 *) ((ulong) & tx4938_pcicptr->g2pcfgdata | +#ifdef __BIG_ENDIAN + ((where & 3) ^ 3)) = val; +#else + (where & 3)) = val; +#endif + break; + case 2: + *(volatile u16 *) ((ulong) & tx4938_pcicptr->g2pcfgdata | +#ifdef __BIG_ENDIAN + ((where & 0x3) ^ 0x2)) = val; +#else + (where & 3)) = val; +#endif + break; + case 4: + tx4938_pcicptr->g2pcfgdata = val; + break; + } + + return check_abort(flags); +} + +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/tx4938/Kconfig b/arch/mips/tx4938/Kconfig new file mode 100644 index 00000000000..d90e9cd8513 --- /dev/null +++ b/arch/mips/tx4938/Kconfig @@ -0,0 +1,24 @@ +if TOSHIBA_RBTX4938 + +comment "Multiplex Pin Select" +choice + prompt "PIO[58:61]" + default TOSHIBA_RBTX4938_MPLEX_PIO58_61 + +config TOSHIBA_RBTX4938_MPLEX_PIO58_61 + bool "PIO" +config TOSHIBA_RBTX4938_MPLEX_NAND + bool "NAND" +config TOSHIBA_RBTX4938_MPLEX_ATA + bool "ATA" + +endchoice + +config TX4938_NAND_BOOT + depends on EXPERIMENTAL && TOSHIBA_RBTX4938_MPLEX_NAND + bool "NAND Boot Support (EXPERIMENTAL)" + help + This is only for Toshiba RBTX4938 reference board, which has NAND IPL. + Select this option if you need to use NAND boot. + +endif diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile new file mode 100644 index 00000000000..74c95c5bcdb --- /dev/null +++ b/arch/mips/tx4938/common/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for common code for Toshiba TX4927 based systems +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o +obj-$(CONFIG_KGDB) += dbgio.o + diff --git a/arch/mips/tx4938/common/dbgio.c b/arch/mips/tx4938/common/dbgio.c new file mode 100644 index 00000000000..bea59ff1842 --- /dev/null +++ b/arch/mips/tx4938/common/dbgio.c @@ -0,0 +1,50 @@ +/* + * linux/arch/mips/tx4938/common/dbgio.c + * + * kgdb interface for gdb + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2005 MontaVista Software Inc. + * + * 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. + * + * Support for TX4938 in 2.6 - Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp> + */ + +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/tx4938/tx4938_mips.h> + +extern u8 txx9_sio_kdbg_rd(void); +extern int txx9_sio_kdbg_wr( u8 ch ); + +u8 getDebugChar(void) +{ + return (txx9_sio_kdbg_rd()); +} + +int putDebugChar(u8 byte) +{ + return (txx9_sio_kdbg_wr(byte)); +} + diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c new file mode 100644 index 00000000000..4f90d7faf63 --- /dev/null +++ b/arch/mips/tx4938/common/irq.c @@ -0,0 +1,424 @@ +/* + * linux/arch/mps/tx4938/common/irq.c + * + * Common tx4938 irq handler + * 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/errno.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/irq.h> +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/tx4938/rbtx4938.h> + +/**********************************************************************************/ +/* Forwad definitions for all pic's */ +/**********************************************************************************/ + +static unsigned int tx4938_irq_cp0_startup(unsigned int irq); +static void tx4938_irq_cp0_shutdown(unsigned int irq); +static void tx4938_irq_cp0_enable(unsigned int irq); +static void tx4938_irq_cp0_disable(unsigned int irq); +static void tx4938_irq_cp0_mask_and_ack(unsigned int irq); +static void tx4938_irq_cp0_end(unsigned int irq); + +static unsigned int tx4938_irq_pic_startup(unsigned int irq); +static void tx4938_irq_pic_shutdown(unsigned int irq); +static void tx4938_irq_pic_enable(unsigned int irq); +static void tx4938_irq_pic_disable(unsigned int irq); +static void tx4938_irq_pic_mask_and_ack(unsigned int irq); +static void tx4938_irq_pic_end(unsigned int irq); + +/**********************************************************************************/ +/* Kernel structs for all pic's */ +/**********************************************************************************/ +DEFINE_SPINLOCK(tx4938_cp0_lock); +DEFINE_SPINLOCK(tx4938_pic_lock); + +#define TX4938_CP0_NAME "TX4938-CP0" +static struct hw_interrupt_type tx4938_irq_cp0_type = { + .typename = TX4938_CP0_NAME, + .startup = tx4938_irq_cp0_startup, + .shutdown = tx4938_irq_cp0_shutdown, + .enable = tx4938_irq_cp0_enable, + .disable = tx4938_irq_cp0_disable, + .ack = tx4938_irq_cp0_mask_and_ack, + .end = tx4938_irq_cp0_end, + .set_affinity = NULL +}; + +#define TX4938_PIC_NAME "TX4938-PIC" +static struct hw_interrupt_type tx4938_irq_pic_type = { + .typename = TX4938_PIC_NAME, + .startup = tx4938_irq_pic_startup, + .shutdown = tx4938_irq_pic_shutdown, + .enable = tx4938_irq_pic_enable, + .disable = tx4938_irq_pic_disable, + .ack = tx4938_irq_pic_mask_and_ack, + .end = tx4938_irq_pic_end, + .set_affinity = NULL +}; + +static struct irqaction tx4938_irq_pic_action = { + .handler = no_action, + .flags = 0, + .mask = CPU_MASK_NONE, + .name = TX4938_PIC_NAME +}; + +/**********************************************************************************/ +/* Functions for cp0 */ +/**********************************************************************************/ + +#define tx4938_irq_cp0_mask(irq) ( 1 << ( irq-TX4938_IRQ_CP0_BEG+8 ) ) + +static void __init +tx4938_irq_cp0_init(void) +{ + int i; + + for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &tx4938_irq_cp0_type; + } + + return; +} + +static unsigned int +tx4938_irq_cp0_startup(unsigned int irq) +{ + tx4938_irq_cp0_enable(irq); + + return (0); +} + +static void +tx4938_irq_cp0_shutdown(unsigned int irq) +{ + tx4938_irq_cp0_disable(irq); +} + +static void +tx4938_irq_cp0_enable(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&tx4938_cp0_lock, flags); + + set_c0_status(tx4938_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4938_cp0_lock, flags); +} + +static void +tx4938_irq_cp0_disable(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&tx4938_cp0_lock, flags); + + clear_c0_status(tx4938_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4938_cp0_lock, flags); + + return; +} + +static void +tx4938_irq_cp0_mask_and_ack(unsigned int irq) +{ + tx4938_irq_cp0_disable(irq); + + return; +} + +static void +tx4938_irq_cp0_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4938_irq_cp0_enable(irq); + } + + return; +} + +/**********************************************************************************/ +/* Functions for pic */ +/**********************************************************************************/ + +u32 +tx4938_irq_pic_addr(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4938_IRQ_PIC_BEG; + + switch (irq) { + case 17: + case 16: + case 1: + case 0:{ + return (TX4938_MKA(TX4938_IRC_IRLVL0)); + } + case 19: + case 18: + case 3: + case 2:{ + return (TX4938_MKA(TX4938_IRC_IRLVL1)); + } + case 21: + case 20: + case 5: + case 4:{ + return (TX4938_MKA(TX4938_IRC_IRLVL2)); + } + case 23: + case 22: + case 7: + case 6:{ + return (TX4938_MKA(TX4938_IRC_IRLVL3)); + } + case 25: + case 24: + case 9: + case 8:{ + return (TX4938_MKA(TX4938_IRC_IRLVL4)); + } + case 27: + case 26: + case 11: + case 10:{ + return (TX4938_MKA(TX4938_IRC_IRLVL5)); + } + case 29: + case 28: + case 13: + case 12:{ + return (TX4938_MKA(TX4938_IRC_IRLVL6)); + } + case 31: + case 30: + case 15: + case 14:{ + return (TX4938_MKA(TX4938_IRC_IRLVL7)); + } + } + + return (0); +} + +u32 +tx4938_irq_pic_mask(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4938_IRQ_PIC_BEG; + + switch (irq) { + case 31: + case 29: + case 27: + case 25: + case 23: + case 21: + case 19: + case 17:{ + return (0x07000000); + } + case 30: + case 28: + case 26: + case 24: + case 22: + case 20: + case 18: + case 16:{ + return (0x00070000); + } + case 15: + case 13: + case 11: + case 9: + case 7: + case 5: + case 3: + case 1:{ + return (0x00000700); + } + case 14: + case 12: + case 10: + case 8: + case 6: + case 4: + case 2: + case 0:{ + return (0x00000007); + } + } + return (0x00000000); +} + +static void +tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits) +{ + unsigned long val = 0; + + val = TX4938_RD(pic_reg); + val &= (~clr_bits); + val |= (set_bits); + TX4938_WR(pic_reg, val); + mmiowb(); + TX4938_RD(pic_reg); + + return; +} + +static void __init +tx4938_irq_pic_init(void) +{ + unsigned long flags; + int i; + + for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &tx4938_irq_pic_type; + } + + setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); + + spin_lock_irqsave(&tx4938_pic_lock, flags); + + TX4938_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ + TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1); /* irq enable */ + + spin_unlock_irqrestore(&tx4938_pic_lock, flags); + + return; +} + +static unsigned int +tx4938_irq_pic_startup(unsigned int irq) +{ + tx4938_irq_pic_enable(irq); + + return (0); +} + +static void +tx4938_irq_pic_shutdown(unsigned int irq) +{ + tx4938_irq_pic_disable(irq); + + return; +} + +static void +tx4938_irq_pic_enable(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&tx4938_pic_lock, flags); + + tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0, + tx4938_irq_pic_mask(irq)); + + spin_unlock_irqrestore(&tx4938_pic_lock, flags); + + return; +} + +static void +tx4938_irq_pic_disable(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&tx4938_pic_lock, flags); + + tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), + tx4938_irq_pic_mask(irq), 0); + + spin_unlock_irqrestore(&tx4938_pic_lock, flags); + + return; +} + +static void +tx4938_irq_pic_mask_and_ack(unsigned int irq) +{ + tx4938_irq_pic_disable(irq); + + return; +} + +static void +tx4938_irq_pic_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4938_irq_pic_enable(irq); + } + + return; +} + +/**********************************************************************************/ +/* Main init functions */ +/**********************************************************************************/ + +void __init +tx4938_irq_init(void) +{ + extern asmlinkage void tx4938_irq_handler(void); + + tx4938_irq_cp0_init(); + tx4938_irq_pic_init(); + set_except_vector(0, tx4938_irq_handler); + + return; +} + +int +tx4938_irq_nested(void) +{ + int sw_irq = 0; + u32 level2; + + level2 = TX4938_RD(0xff1ff6a0); + if ((level2 & 0x10000) == 0) { + level2 &= 0x1f; + sw_irq = TX4938_IRQ_PIC_BEG + level2; + if (sw_irq == 26) { + { + extern int toshiba_rbtx4938_irq_nested(int sw_irq); + sw_irq = toshiba_rbtx4938_irq_nested(sw_irq); + } + } + } + + wbflush(); + return (sw_irq); +} diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S new file mode 100644 index 00000000000..1b2f72bac42 --- /dev/null +++ b/arch/mips/tx4938/common/irq_handler.S @@ -0,0 +1,84 @@ +/* + * linux/arch/mips/tx4938/common/handler.S + * + * Primary interrupt handler for tx4938 based systems + * 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 <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/tx4938/rbtx4938.h> + + + .align 5 + NESTED(tx4938_irq_handler, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 t0, CP0_CAUSE + mfc0 t1, CP0_STATUS + and t0, t1 + + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_ip7 + + /* IP6..IP3 multiplexed -- do not use */ + + andi t1, t0, STATUSF_IP2 /* tx4938 pic */ + bnez t1, ll_ip2 + + andi t1, t0, STATUSF_IP1 /* user line 1 */ + bnez t1, ll_ip1 + + andi t1, t0, STATUSF_IP0 /* user line 0 */ + bnez t1, ll_ip0 + + .set reorder + + nop + END(tx4938_irq_handler) + + .align 5 + + +ll_ip7: + li a0, TX4938_IRQ_CPU_TIMER + move a1, sp + jal do_IRQ + j ret_from_irq + + +ll_ip2: + jal tx4938_irq_nested + nop + beqz v0, goto_spurious_interrupt + nop + move a0, v0 + move a1, sp + jal do_IRQ + j ret_from_irq + +goto_spurious_interrupt: + j ret_from_irq + +ll_ip1: + li a0, TX4938_IRQ_USER1 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip0: + li a0, TX4938_IRQ_USER0 + move a1, sp + jal do_IRQ + j ret_from_irq diff --git a/arch/mips/tx4938/common/prom.c b/arch/mips/tx4938/common/prom.c new file mode 100644 index 00000000000..3189a65f7d7 --- /dev/null +++ b/arch/mips/tx4938/common/prom.c @@ -0,0 +1,129 @@ +/* + * linux/arch/mips/tx4938/common/prom.c + * + * common tx4938 memory interface + * 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/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/tx4938/tx4938.h> + +static unsigned int __init +tx4938_process_sdccr(u64 * addr) +{ + u64 val; + unsigned int sdccr_ce; + unsigned int sdccr_rs; + unsigned int sdccr_cs; + unsigned int sdccr_mw; + unsigned int rs = 0; + unsigned int cs = 0; + unsigned int mw = 0; + unsigned int bc = 4; + unsigned int msize = 0; |