diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/tx4927 |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/mips/tx4927')
-rw-r--r-- | arch/mips/tx4927/common/Makefile | 12 | ||||
-rw-r--r-- | arch/mips/tx4927/common/tx4927_dbgio.c | 47 | ||||
-rw-r--r-- | arch/mips/tx4927/common/tx4927_irq.c | 584 | ||||
-rw-r--r-- | arch/mips/tx4927/common/tx4927_irq_handler.S | 103 | ||||
-rw-r--r-- | arch/mips/tx4927/common/tx4927_prom.c | 146 | ||||
-rw-r--r-- | arch/mips/tx4927/common/tx4927_setup.c | 237 | ||||
-rw-r--r-- | arch/mips/tx4927/toshiba_rbtx4927/Makefile | 5 | ||||
-rw-r--r-- | arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 786 | ||||
-rw-r--r-- | arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c | 97 | ||||
-rw-r--r-- | arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c | 1024 |
10 files changed, 3041 insertions, 0 deletions
diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile new file mode 100644 index 00000000000..8fa126b296e --- /dev/null +++ b/arch/mips/tx4927/common/Makefile @@ -0,0 +1,12 @@ +# +# 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 += tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o + +obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o +obj-$(CONFIG_KGDB) += tx4927_dbgio.o diff --git a/arch/mips/tx4927/common/tx4927_dbgio.c b/arch/mips/tx4927/common/tx4927_dbgio.c new file mode 100644 index 00000000000..09bdf2baa83 --- /dev/null +++ b/arch/mips/tx4927/common/tx4927_dbgio.c @@ -0,0 +1,47 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_dbgio.c + * + * kgdb interface for gdb + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ + +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/tx4927/tx4927_mips.h> + +u8 getDebugChar(void) +{ + extern u8 txx9_sio_kdbg_rd(void); + return (txx9_sio_kdbg_rd()); +} + + +int putDebugChar(u8 byte) +{ + extern int txx9_sio_kdbg_wr( u8 ch ); + return (txx9_sio_kdbg_wr(byte)); +} diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c new file mode 100644 index 00000000000..5ab2e2b7601 --- /dev/null +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -0,0 +1,584 @@ +/* + * Common tx4927 irq handler + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/config.h> +#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 <linux/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/tx4927/tx4927.h> + +/* + * DEBUG + */ + +#undef TX4927_IRQ_DEBUG + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_NONE 0x00000000 + +#define TX4927_IRQ_INFO ( 1 << 0 ) +#define TX4927_IRQ_WARN ( 1 << 1 ) +#define TX4927_IRQ_EROR ( 1 << 2 ) + +#define TX4927_IRQ_INIT ( 1 << 5 ) +#define TX4927_IRQ_NEST1 ( 1 << 6 ) +#define TX4927_IRQ_NEST2 ( 1 << 7 ) +#define TX4927_IRQ_NEST3 ( 1 << 8 ) +#define TX4927_IRQ_NEST4 ( 1 << 9 ) + +#define TX4927_IRQ_CP0_INIT ( 1 << 10 ) +#define TX4927_IRQ_CP0_STARTUP ( 1 << 11 ) +#define TX4927_IRQ_CP0_SHUTDOWN ( 1 << 12 ) +#define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) +#define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) +#define TX4927_IRQ_CP0_MASK ( 1 << 15 ) +#define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) + +#define TX4927_IRQ_PIC_INIT ( 1 << 20 ) +#define TX4927_IRQ_PIC_STARTUP ( 1 << 21 ) +#define TX4927_IRQ_PIC_SHUTDOWN ( 1 << 22 ) +#define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) +#define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) +#define TX4927_IRQ_PIC_MASK ( 1 << 25 ) +#define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) + +#define TX4927_IRQ_ALL 0xffffffff +#endif + +#ifdef TX4927_IRQ_DEBUG +static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE + | TX4927_IRQ_INFO + | TX4927_IRQ_WARN | TX4927_IRQ_EROR +// | TX4927_IRQ_CP0_INIT +// | TX4927_IRQ_CP0_STARTUP +// | TX4927_IRQ_CP0_SHUTDOWN +// | TX4927_IRQ_CP0_ENABLE +// | TX4927_IRQ_CP0_DISABLE +// | TX4927_IRQ_CP0_MASK +// | TX4927_IRQ_CP0_ENDIRQ +// | TX4927_IRQ_PIC_INIT +// | TX4927_IRQ_PIC_STARTUP +// | TX4927_IRQ_PIC_SHUTDOWN +// | TX4927_IRQ_PIC_ENABLE +// | TX4927_IRQ_PIC_DISABLE +// | TX4927_IRQ_PIC_MASK +// | TX4927_IRQ_PIC_ENDIRQ +// | TX4927_IRQ_INIT +// | TX4927_IRQ_NEST1 +// | TX4927_IRQ_NEST2 +// | TX4927_IRQ_NEST3 +// | TX4927_IRQ_NEST4 + ); +#endif + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_DPRINTK(flag,str...) \ + if ( (tx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TX4927_IRQ_DPRINTK(flag,str...) +#endif + +/* + * Forwad definitions for all pic's + */ + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq); +static void tx4927_irq_cp0_shutdown(unsigned int irq); +static void tx4927_irq_cp0_enable(unsigned int irq); +static void tx4927_irq_cp0_disable(unsigned int irq); +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq); +static void tx4927_irq_cp0_end(unsigned int irq); + +static unsigned int tx4927_irq_pic_startup(unsigned int irq); +static void tx4927_irq_pic_shutdown(unsigned int irq); +static void tx4927_irq_pic_enable(unsigned int irq); +static void tx4927_irq_pic_disable(unsigned int irq); +static void tx4927_irq_pic_mask_and_ack(unsigned int irq); +static void tx4927_irq_pic_end(unsigned int irq); + +/* + * Kernel structs for all pic's + */ + +static DEFINE_SPINLOCK(tx4927_cp0_lock); +static DEFINE_SPINLOCK(tx4927_pic_lock); + +#define TX4927_CP0_NAME "TX4927-CP0" +static struct hw_interrupt_type tx4927_irq_cp0_type = { + .typename = TX4927_CP0_NAME, + .startup = tx4927_irq_cp0_startup, + .shutdown = tx4927_irq_cp0_shutdown, + .enable = tx4927_irq_cp0_enable, + .disable = tx4927_irq_cp0_disable, + .ack = tx4927_irq_cp0_mask_and_ack, + .end = tx4927_irq_cp0_end, + .set_affinity = NULL +}; + +#define TX4927_PIC_NAME "TX4927-PIC" +static struct hw_interrupt_type tx4927_irq_pic_type = { + .typename = TX4927_PIC_NAME, + .startup = tx4927_irq_pic_startup, + .shutdown = tx4927_irq_pic_shutdown, + .enable = tx4927_irq_pic_enable, + .disable = tx4927_irq_pic_disable, + .ack = tx4927_irq_pic_mask_and_ack, + .end = tx4927_irq_pic_end, + .set_affinity = NULL +}; + +#define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } +static struct irqaction tx4927_irq_pic_action = +TX4927_PIC_ACTION(TX4927_PIC_NAME); + +#define CCP0_STATUS 12 +#define CCP0_CAUSE 13 + +/* + * Functions for cp0 + */ + +#define tx4927_irq_cp0_mask(irq) ( 1 << ( irq-TX4927_IRQ_CP0_BEG+8 ) ) + +static void +tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, unsigned set_bits) +{ + unsigned long val = 0; + + switch (cp0_reg) { + case CCP0_STATUS: + val = read_c0_status(); + break; + + case CCP0_CAUSE: + val = read_c0_cause(); + break; + + } + + val &= (~clr_bits); + val |= (set_bits); + + switch (cp0_reg) { + case CCP0_STATUS:{ + write_c0_status(val); + break; + } + case CCP0_CAUSE:{ + write_c0_cause(val); + break; + } + } + + return; +} + +static void __init tx4927_irq_cp0_init(void) +{ + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n", + TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); + + for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &tx4927_irq_cp0_type; + } + + return; +} + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq); + + tx4927_irq_cp0_enable(irq); + + return (0); +} + +static void tx4927_irq_cp0_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq); + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq); + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq); + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_cp0_enable(irq); + } + + return; +} + +/* + * Functions for pic + */ +u32 tx4927_irq_pic_addr(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_IRQ_PIC_BEG; + switch (irq) { + case 17: + case 16: + case 1: + case 0: + return (0xff1ff610); + + case 19: + case 18: + case 3: + case 2: + return (0xff1ff614); + + case 21: + case 20: + case 5: + case 4: + return (0xff1ff618); + + case 23: + case 22: + case 7: + case 6: + return (0xff1ff61c); + + case 25: + case 24: + case 9: + case 8: + return (0xff1ff620); + + case 27: + case 26: + case 11: + case 10: + return (0xff1ff624); + + case 29: + case 28: + case 13: + case 12: + return (0xff1ff628); + + case 31: + case 30: + case 15: + case 14: + return (0xff1ff62c); + + } + return (0); +} + +u32 tx4927_irq_pic_mask(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_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 tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, + unsigned set_bits) +{ + unsigned long val = 0; + + val = TX4927_RD(pic_reg); + val &= (~clr_bits); + val |= (set_bits); + TX4927_WR(pic_reg, val); + + return; +} + +static void __init tx4927_irq_pic_init(void) +{ + unsigned long flags; + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n", + TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); + + for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &tx4927_irq_pic_type; + } + + setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + TX4927_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ + TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1); /* irq enable */ + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static unsigned int tx4927_irq_pic_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq); + + tx4927_irq_pic_enable(irq); + + return (0); +} + +static void tx4927_irq_pic_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq); + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, + tx4927_irq_pic_mask(irq)); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), + tx4927_irq_pic_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq); + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq); + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_pic_enable(irq); + } + + return; +} + +/* + * Main init functions + */ +void __init tx4927_irq_init(void) +{ + extern asmlinkage void tx4927_irq_handler(void); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); + tx4927_irq_cp0_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); + tx4927_irq_pic_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, + "=Calling set_except_vector(tx4927_irq_handler)\n"); + set_except_vector(0, tx4927_irq_handler); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); + + return; +} + +int tx4927_irq_nested(void) +{ + int sw_irq = 0; + u32 level2; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "-\n"); + + level2 = TX4927_RD(0xff1ff6a0); + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=level2a=0x%x\n", level2); + + if ((level2 & 0x10000) == 0) { + level2 &= 0x1f; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=level2b=0x%x\n", level2); + + sw_irq = TX4927_IRQ_PIC_BEG + level2; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=sw_irq=%d\n", sw_irq); + + if (sw_irq == 27) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq-%d\n", + sw_irq); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + sw_irq = toshiba_rbtx4927_irq_nested(sw_irq); + } +#endif + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq+%d\n", + sw_irq); + } + } + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=sw_irq=%d\n", sw_irq); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "+\n"); + + return (sw_irq); +} diff --git a/arch/mips/tx4927/common/tx4927_irq_handler.S b/arch/mips/tx4927/common/tx4927_irq_handler.S new file mode 100644 index 00000000000..ca123e28d1e --- /dev/null +++ b/arch/mips/tx4927/common/tx4927_irq_handler.S @@ -0,0 +1,103 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_irq_handler.S + * + * Primary interrupt handler for tx4927 based systems + * + * Author: MontaVista Software, Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * source@mvista.com + * + * Copyright 2001-2002 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. + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/tx4927/tx4927.h> + + .align 5 + NESTED(tx4927_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 /* tx4927 pic */ + bnez t1, ll_ip2 + + andi t1, t0, STATUSF_IP0 /* user line 0 */ + bnez t1, ll_ip0 + + andi t1, t0, STATUSF_IP1 /* user line 1 */ + bnez t1, ll_ip1 + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(tx4927_irq_handler) + + .align 5 + + +ll_ip7: + li a0, TX4927_IRQ_CPU_TIMER + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip2: + jal tx4927_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 spurious_interrupt + nop + +ll_ip1: + li a0, TX4927_IRQ_USER1 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip0: + li a0, TX4927_IRQ_USER0 + move a1, sp + jal do_IRQ + j ret_from_irq diff --git a/arch/mips/tx4927/common/tx4927_prom.c b/arch/mips/tx4927/common/tx4927_prom.c new file mode 100644 index 00000000000..7d4cbf512d8 --- /dev/null +++ b/arch/mips/tx4927/common/tx4927_prom.c @@ -0,0 +1,146 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_prom.c + * + * common tx4927 memory interface + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ + +#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/tx4927/tx4927.h> + +static unsigned int __init tx4927_process_sdccr(u64 * addr) +{ + u64 val; + unsigned int sdccr_ce; + unsigned int sdccr_bs; + unsigned int sdccr_rs; + unsigned int sdccr_cs; + unsigned int sdccr_mw; + unsigned int bs = 0; + unsigned int rs = 0; + unsigned int cs = 0; + unsigned int mw = 0; + unsigned int msize = 0; + + val = (*((vu64 *) (addr))); + + /* MVMCP -- need #defs for these bits masks */ + sdccr_ce = ((val & (1 << 10)) >> 10); + sdccr_bs = ((val & (1 << 8)) >> 8); + sdccr_rs = ((val & (3 << 5)) >> 5); + sdccr_cs = ((val & (3 << 2)) >> 2); + sdccr_mw = ((val & (1 << 0)) >> 0); + + if (sdccr_ce) { + switch (sdccr_bs) { + case 0:{ + bs = 2; + break; + } + case 1:{ + bs = 4; + break; + } + } + switch (sdccr_rs) { + case 0:{ + rs = 2048; + break; + } + case 1:{ + rs = 4096; + break; + } + case 2:{ + rs = 8192; + break; + } + case 3:{ + rs = 0; + break; + } + } + switch (sdccr_cs) { + case 0:{ + cs = 256; + break; + } + case 1:{ + cs = 512; + break; + } + case 2:{ + cs = 1024; + break; + } + case 3:{ + cs = 2048; + break; + } + } + switch (sdccr_mw) { + case 0:{ + mw = 8; + break; + } /* 8 bytes = 64 bits */ + case 1:{ + mw = 4; + break; + } /* 4 bytes = 32 bits */ + } + } + + /* bytes per chip MB per chip num chips */ + msize = (((rs * cs * mw) / (1024 * 1024)) * bs); + + return (msize); +} + + +unsigned int __init tx4927_get_mem_size(void) +{ + unsigned int c0; + unsigned int c1; + unsigned int c2; + unsigned int c3; + unsigned int total; + + /* MVMCP -- need #defs for these registers */ + c0 = tx4927_process_sdccr((u64 *) 0xff1f8000); + c1 = tx4927_process_sdccr((u64 *) 0xff1f8008); + c2 = tx4927_process_sdccr((u64 *) 0xff1f8010); + c3 = tx4927_process_sdccr((u64 *) 0xff1f8018); + total = c0 + c1 + c2 + c3; + + return (total); +} diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c new file mode 100644 index 00000000000..16bcbdc6d1c --- /dev/null +++ b/arch/mips/tx4927/common/tx4927_setup.c @@ -0,0 +1,237 @@ +/* + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ +#include <linux/config.h> +#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 <linux/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/time.h> +#include <asm/tx4927/tx4927.h> + + +#undef DEBUG + +void __init tx4927_time_init(void); +void __init tx4927_timer_setup(struct irqaction *irq); +void dump_cp0(char *key); + + +void (*__wbflush) (void); + +static void tx4927_write_buffer_flush(void) +{ + __asm__ __volatile__ + ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t"); +} + + +static void __init tx4927_setup(void) +{ + board_time_init = tx4927_time_init; + board_timer_setup = tx4927_timer_setup; + __wbflush = tx4927_write_buffer_flush; + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_setup(void); + toshiba_rbtx4927_setup(); + } +#endif + + return; +} + +early_initcall(tx4927_setup); + +void __init tx4927_time_init(void) +{ + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_time_init(void); + toshiba_rbtx4927_time_init(); + } +#endif + + return; +} + + +void __init tx4927_timer_setup(struct irqaction *irq) +{ + u32 count; + u32 c1; + u32 c2; + + setup_irq(TX4927_IRQ_CPU_TIMER, irq); + + /* to generate the first timer interrupt */ + c1 = read_c0_count(); + count = c1 + (mips_hpt_frequency / HZ); + write_c0_compare(count); + c2 = read_c0_count(); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_timer_setup(struct irqaction + *irq); + toshiba_rbtx4927_timer_setup(irq); + } +#endif + + return; +} + + +#ifdef DEBUG +void print_cp0(char *key, int num, char *name, u32 val) +{ + printk("%s cp0:%02d:%s=0x%08x\n", key, num, name, val); + return; +} + +indent: Standard input:25: Error:Unexpected end of file + +void +dump_cp0(char *key) +{ + if (key == NULL) + key = ""; + + print_cp0(key, 0, "INDEX ", read_c0_index()); + print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0()); + print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1()); + print_cp0(key, 4, "CONTEXT ", read_c0_context()); + print_cp0(key, 5, "PAGEMASK", read_c0_pagemask()); + print_cp0(key, 6, "WIRED ", read_c0_wired()); + //print_cp0(key, 8, "BADVADDR", read_c0_badvaddr()); + print_cp0(key, 9, "COUNT ", read_c0_count()); + print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi()); + print_cp0(key, 11, "COMPARE ", read_c0_compare()); + print_cp0(key, 12, "STATUS ", read_c0_status()); + print_cp0(key, 13, "CAUSE ", read_c0_cause() & 0xffff87ff); + print_cp0(key, 16, "CONFIG ", read_c0_config()); + return; +} + +void print_pic(char *key, u32 reg, char *name) +{ + printk("%s pic:0x%08x:%s=0x%08x\n", key, reg, name, + TX4927_RD(reg)); + return; +} + + +void dump_pic(char *key) +{ + if (key == NULL) + key = ""; + + print_pic(key, 0xff1ff600, "IRDEN "); + print_pic(key, 0xff1ff604, "IRDM0 "); + print_pic(key, 0xff1ff608, "IRDM1 "); + + print_pic(key, 0xff1ff610, "IRLVL0 "); + print_pic(key, 0xff1ff614, "IRLVL1 "); + print_pic(key, 0xff1ff618, "IRLVL2 "); + print_pic(key, 0xff1ff61c, "IRLVL3 "); + print_pic(key, 0xff1ff620, "IRLVL4 "); + print_pic(key, 0xff1ff624, "IRLVL5 "); + print_pic(key, 0xff1ff628, "IRLVL6 "); + print_pic(key, 0xff1ff62c, "IRLVL7 "); + + print_pic(key, 0xff1ff640, "IRMSK "); + print_pic(key, 0xff1ff660, "IREDC "); + print_pic(key, 0xff1ff680, "IRPND "); + print_pic(key, 0xff1ff6a0, "IRCS "); + + print_pic(key, 0xff1ff514, "IRFLAG1 "); /* don't read IRLAG0 -- it hangs system */ + + print_pic(key, 0xff1ff518, "IRPOL "); + print_pic(key, 0xff1ff51c, "IRRCNT "); + print_pic(key, 0xff1ff520, "IRMASKINT"); + print_pic(key, 0xff1ff524, "IRMASKEXT"); + + return; +} + + +void print_addr(char *hdr, char *key, u32 addr) +{ + printk("%s %s:0x%08x=0x%08x\n", hdr, key, addr, TX4927_RD(addr)); + return; +} + + +void dump_180(char *key) +{ + u32 i; + + for (i = 0x80000180; i < 0x80000180 + 0x80; i += 4) { + print_addr("180", key, i); + } + return; +} + + +void dump_eh0(char *key) +{ + int i; + extern unsigned long exception_handlers[]; + + for (i = (int) exception_handlers; + i < (int) (exception_handlers + 20); i += 4) { + print_addr("eh0", key, i); + } + + return; +} + +void pk0(void) +{ + volatile u32 val; + + __asm__ __volatile__("ori %0, $26, 0":"=r"(val) + ); + printk("k0=[0x%08x]\n", val); +} +#endif diff --git a/arch/mips/tx4927/toshiba_rbtx4927/Makefile b/arch/mips/tx4927/toshiba_rbtx4927/Makefile new file mode 100644 index 00000000000..86ca4cf2d58 --- /dev/null +++ b/arch/mips/tx4927/toshiba_rbtx4927/Makefile @@ -0,0 +1,5 @@ +obj-y += toshiba_rbtx4927_prom.o +obj-y += toshiba_rbtx4927_setup.o +obj-y += toshiba_rbtx4927_irq.o + +EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c new file mode 100644 index 00000000000..fd5b433f83b --- /dev/null +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -0,0 +1,786 @@ +/* + * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c + * + * Toshiba RBTX4927 specific interrupt handlers + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ + + +/* +IRQ Device +00 RBTX4927-ISA/00 +01 RBTX4927-ISA/01 PS2/Keyboard +02 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15) +03 RBTX4927-ISA/03 +04 RBTX4927-ISA/04 +05 RBTX4927-ISA/05 +06 RBTX4927-ISA/06 +07 RBTX4927-ISA/07 +08 RBTX4927-ISA/08 +09 RBTX4927-ISA/09 +10 RBTX4927-ISA/10 +11 RBTX4927-ISA/11 +12 RBTX4927-ISA/12 PS2/Mouse (not supported at this time) +13 RBTX4927-ISA/13 +14 RBTX4927-ISA/14 IDE +15 RBTX4927-ISA/15 + +16 TX4927-CP0/00 Software 0 +17 TX4927-CP0/01 Software 1 +18 TX4927-CP0/02 Cascade TX4927-CP0 +19 TX4927-CP0/03 Multiplexed -- do not use +20 TX4927-CP0/04 Multiplexed -- do not use +21 TX4927-CP0/05 Multiplexed -- do not use +22 TX4927-CP0/06 Multiplexed -- do not use +23 TX4927-CP0/07 CPU TIMER + +24 TX4927-PIC/00 +25 TX4927-PIC/01 +26 TX4927-PIC/02 +27 TX4927-PIC/03 Cascade RBTX4927-IOC +28 TX4927-PIC/04 +29 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet +30 TX4927-PIC/06 +31 TX4927-PIC/07 +32 TX4927-PIC/08 TX4927 SerialIO Channel 0 +33 TX4927-PIC/09 TX4927 SerialIO Channel 1 +34 TX4927-PIC/10 +35 TX4927-PIC/11 +36 TX4927-PIC/12 +37 TX4927-PIC/13 +38 TX4927-PIC/14 +39 TX4927-PIC/15 +40 TX4927-PIC/16 TX4927 PCI PCI-C +41 TX4927-PIC/17 +42 TX4927-PIC/18 +43 TX4927-PIC/19 +44 TX4927-PIC/20 +45 TX4927-PIC/21 +46 TX4927-PIC/22 TX4927 PCI PCI-ERR +47 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used) +48 TX4927-PIC/24 +49 TX4927-PIC/25 +50 TX4927-PIC/26 +51 TX4927-PIC/27 +52 TX4927-PIC/28 +53 TX4927-PIC/29 +54 TX4927-PIC/30 +55 TX4927-PIC/31 + +56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4] +57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5] +58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported] +59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6] +60 RBTX4927-IOC/04 +61 RBTX4927-IOC/05 +62 RBTX4927-IOC/06 +63 RBTX4927-IOC/07 + +NOTES: +SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58 +SouthBridge/ISA/pin=0 no pci irq used by this device +SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14 +SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59 +SouthBridge/PMC/pin=0 no pci irq used by this device +SuperIO/PS2/Keyboard, using INTR via ISA IRQ1 +SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported) +JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6 +*/ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/timex.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <linux/bootmem.h> +#include <linux/blkdev.h> +#ifdef CONFIG_RTC_DS1742 +#include <linux/ds1742rtc.h> +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include <asm/tx4927/smsc_fdc37m81x.h> +#endif +#include <asm/tx4927/toshiba_rbtx4927.h> + + +#undef TOSHIBA_RBTX4927_IRQ_DEBUG + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_IRQ_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_IRQ_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_IRQ_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_STARTUP ( 1 << 11 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN ( 1 << 12 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_MASK ( 1 << 15 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) + +#define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_STARTUP ( 1 << 21 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN ( 1 << 22 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE ( 1 << 24 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_MASK ( 1 << 25 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ ( 1 << 26 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +static const u32 toshiba_rbtx4927_irq_debug_flag = + (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO | + TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR +// | TOSHIBA_RBTX4927_IRQ_IOC_INIT +// | TOSHIBA_RBTX4927_IRQ_IOC_STARTUP +// | TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_MASK +// | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ +// | TOSHIBA_RBTX4927_IRQ_ISA_INIT +// | TOSHIBA_RBTX4927_IRQ_ISA_STARTUP +// | TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_MASK +// | TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ + ); +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) +#endif + + + + +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 + +#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */ +#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */ + + +#define TOSHIBA_RBTX4927_IRQ_ISA_BEG MI8259_IRQ_ISA_BEG +#define TOSHIBA_RBTX4927_IRQ_ISA_END MI8259_IRQ_ISA_END +#define TOSHIBA_RBTX4927_IRQ_ISA_MID ((TOSHIBA_RBTX4927_IRQ_ISA_BEG+TOSHIBA_RBTX4927_IRQ_ISA_END+1)/2) + + +#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) +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA (TOSHIBA_RBTX4927_IRQ_ISA_BEG+2) + +extern int tx4927_using_backplane; + +#ifdef CONFIG_TOSHIBA_FPCIB0 +extern void enable_8259A_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void mask_and_ack_8259A(unsigned int irq); +#endif + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq); +#endif + +static DEFINE_SPINLOCK(toshiba_rbtx4927_ioc_lock); + + +#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" +static struct hw_interrupt_type toshiba_rbtx4927_irq_ioc_type = { + .typename = TOSHIBA_RBTX4927_IOC_NAME, + .startup = toshiba_rbtx4927_irq_ioc_startup, + .shutdown = toshiba_rbtx4927_irq_ioc_shutdown, + .enable = toshiba_rbtx4927_irq_ioc_enable, + .disable = toshiba_rbtx4927_irq_ioc_disable, + .ack = toshiba_rbtx4927_irq_ioc_mask_and_ack, + .end = toshiba_rbtx4927_irq_ioc_end, + .set_affinity = NULL +}; +#define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 +#define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +#define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA" +static struct hw_interrupt_type toshiba_rbtx4927_irq_isa_type = { + .typename = TOSHIBA_RBTX4927_ISA_NAME, + .startup = toshiba_rbtx4927_irq_isa_startup, + .shutdown = toshiba_rbtx4927_irq_isa_shutdown, + .enable = toshiba_rbtx4927_irq_isa_enable, + .disable = toshiba_rbtx4927_irq_isa_disable, + .ack = toshiba_rbtx4927_irq_isa_mask_and_ack, + .end = toshiba_rbtx4927_irq_isa_end, + .set_affinity = NULL +}; +#endif + + +u32 bit2num(u32 num) +{ + u32 i; + + for (i = 0; i < (sizeof(num) * 8); i++) { + if (num & (1 << i)) { + return (i); + } + } + return (0); +} + +int toshiba_rbtx4927_irq_nested(int sw_irq) +{ + u32 level3; + u32 level4; + u32 level5; + + level3 = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + if (level3) { + sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + bit2num(level3); + if (sw_irq != TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC) { + goto RETURN; + } + } +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + outb(0x0A, 0x20); + level4 = inb(0x20) & 0xff; + if (level4) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_BEG + + bit2num(level4); + if (sw_irq != + TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA) { + goto RETURN; + } + } + + outb(0x0A, 0xA0); + level5 = inb(0xA0) & 0xff; + if (level5) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_MID + + bit2num(level5); + goto RETURN; + } + } + } +#endif + + RETURN: + return (sw_irq); +} + +//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } +#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, CPU_MASK_NONE, s, NULL, NULL } +static struct irqaction toshiba_rbtx4927_irq_ioc_action = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME); +#ifdef CONFIG_TOSHIBA_FPCIB0 +static struct irqaction toshiba_rbtx4927_irq_isa_master = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/M"); +static struct irqaction toshiba_rbtx4927_irq_isa_slave = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/S"); +#endif + + +/**********************************************************************************/ +/* Functions for ioc */ +/**********************************************************************************/ + + +static void __init toshiba_rbtx4927_irq_ioc_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_IOC_BEG, + TOSHIBA_RBTX4927_IRQ_IOC_END); + + for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; + i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 3; + irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, + &toshiba_rbtx4927_irq_ioc_action); + + return; +} + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_enable(irq); + + return (0); +} + + +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_ioc_enable(irq); + } + + return; +} + + +/**********************************************************************************/ +/* Functions for isa */ +/**********************************************************************************/ + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void __init toshiba_rbtx4927_irq_isa_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_ISA_BEG, + TOSHIBA_RBTX4927_IRQ_ISA_END); + + for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG; + i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = + ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); + irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, + &toshiba_rbtx4927_irq_isa_master); + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA, + &toshiba_rbtx4927_irq_isa_slave); + + /* make sure we are looking at IRR (not ISR) */ + outb(0x0A, 0x20); + outb(0x0A, 0xA0); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_enable(irq); + + return (0); +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_disable(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + enable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + disable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + mask_and_ack_8259A(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_isa_enable(irq); + } + + return; +} +#endif + + +void __init arch_init_irq(void) +{ + extern void tx4927_irq_init(void); + + local_irq_disable(); + + tx4927_irq_init(); + toshiba_rbtx4927_irq_ioc_init(); +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + toshiba_rbtx4927_irq_isa_init(); + } + } +#endif + + wbflush(); + + return; +} + +void toshiba_rbtx4927_irq_dump(char *key) +{ +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG + { + u32 i, j = 0; + for (i = 0; i < NR_IRQS; i++) { + if (strcmp(irq_desc[i].handler->typename, "none") + == 0) + continue; + + if ((i >= 1) + && (irq_desc[i - 1].handler->typename == + irq_desc[i].handler->typename)) { + j++; + } else { + j = 0; + } + TOSHIBA_RBTX4927_IRQ_DPRINTK + (TOSHIBA_RBTX4927_IRQ_INFO, + "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", + key, i, i, irq_desc[i].status, + (u32) irq_desc[i].handler, + (u32) irq_desc[i].action, + (u32) (irq_desc[i].action ? irq_desc[i]. + action->handler : 0), + irq_desc[i].depth, + irq_desc[i].handler->typename, j); + } + } +#endif + return; +} + +void toshiba_rbtx4927_irq_dump_pics(char *s) +{ + u32 level0_m; + u32 level0_s; + u32 level1_m; + u32 level1_s; + u32 level2; + u32 level2_p; + u32 level2_s; + u32 level3_m; + u32 level3_s; + u32 level4_m; + u32 level4_s; + u32 level5_m; + u32 level5_s; + + if (s == NULL) + s = "null"; + + level0_m = (read_c0_status() & 0x0000ff00) >> 8; + level0_s = (read_c0_cause() & 0x0000ff00) >> 8; + + level1_m = level0_m; + level1_s = level0_s & 0x87; + + level2 = TX4927_RD(0xff1ff6a0); + level2_p = (((level2 & 0x10000)) ? 0 : 1); + level2_s = (((level2 & 0x1f) == 0x1f) ? 0 : (level2 & 0x1f)); + + level3_m = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_ENAB) & 0x1f; + level3_s = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + + level4_m = inb(0x21); + outb(0x0A, 0x20); + level4_s = inb(0x20); + + level5_m = inb(0xa1); + outb(0x0A, 0xa0); + level5_s = inb(0xa0); + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "dump_raw_pic() "); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level0_m, + level0_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level1_m, + level1_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "pic:e=0x%02x/s=0x%02x ", level2_p, + level2_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "ioc:m=0x%02x/s=0x%02x ", level3_m, + level3_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbm:m=0x%02x/s=0x%02x ", level4_m, + level4_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbs:m=0x%02x/s=0x%02x ", level5_m, + level5_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n", + s); + + return; +} diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c new file mode 100644 index 00000000000..e4d095d3e19 --- /dev/null +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c @@ -0,0 +1,97 @@ +/* + * rbtx4927 specific prom routines + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * Copyright (C) 2004 MontaVista Software Inc. + * Author: Manish Lachwani, mlachwani@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/tx4927/tx4927.h> + +void __init prom_init_cmdline(void) +{ + int argc = (int) fw_arg0; + char **argv = (char **) fw_arg1; + int i; /* Always ignore the "-c" at argv[0] */ + + /* ignore all built-in args if any f/w args given */ + if (argc > 1) { + *arcs_cmdline = '\0'; + } + + for (i = 1; i < argc; i++) { + if (i != 1) { + strcat(arcs_cmdline, " "); + } + strcat(arcs_cmdline, argv[i]); + } +} + +void __init prom_init(void) +{ + const char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES; + extern int tx4927_get_mem_size(void); + extern char* toshiba_name; + int msize; + + prom_init_cmdline(); + + mips_machgroup = MACH_GROUP_TOSHIBA; + + if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) + mips_machtype = MACH_TOSHIBA_RBTX4927; + else + mips_machtype = MACH_TOSHIBA_RBTX4937; + + toshiba_name = toshiba_name_list[mips_machtype]; + + msize = tx4927_get_mem_size(); + add_memory_region(0, msize << 20, BOOT_MEM_RAM); +} + +unsigned long __init prom_free_prom_memory(void) +{ + return 0; +} + +const char *get_system_type(void) +{ + return "Toshiba RBTX4927/RBTX4937"; +} + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c new file mode 100644 index 00000000000..8724ea3ae04 --- /dev/null +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -0,0 +1,1024 @@ +/* + * Toshiba rbtx4927 specific setup + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2002 MontaVista Software Inc. + * Author: Michael Pruznick, michael_pruznick@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * Copyright (C) 2004 MontaVista Software Inc. + * Author: Manish Lachwani, mlachwani@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/timex.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <linux/bootmem.h> +#include <linux/blkdev.h> +#ifdef CONFIG_RTC_DS1742 +#include <linux/ds1742rtc.h> +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include <asm/tx4927/smsc_fdc37m81x.h> +#endif +#include <asm/tx4927/toshiba_rbtx4927.h> +#ifdef CONFIG_PCI +#include <asm/tx4927/tx4927_pci.h> +#endif +#ifdef CONFIG_BLK_DEV_IDEPCI +#include <linux/hdreg.h> +#include <linux/ide.h> +#endif + +#undef TOSHIBA_RBTX4927_SETUP_DEBUG + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_SETUP_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_SETUP_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_SETUP_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 ) +#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) +#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 ) +#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 ) +#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) +#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) +#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) +#define TOSHIBA_RBTX4927_SETUP_PCI66 ( 1 << 10 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +static const u32 toshiba_rbtx4927_setup_debug_flag = + (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | + TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR | + TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP | + TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP + | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | + TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66); +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_setup_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) +#endif + +/* These functions are used for rebooting or halting the machine*/ +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 gt64120_time_init(void); +extern void toshiba_rbtx4927_irq_setup(void); + +#ifdef CONFIG_PCI +#define CONFIG_TX4927BUG_WORKAROUND +#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]; +void tx4927_pci_setup(void); +void tx4927_reset_pci_pcic(void); +int tx4927_pci66 = 0; /* 0:auto */ +#endif + +char *toshiba_name = ""; + +#ifdef CONFIG_PCI +static void tx4927_pcierr_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ +#ifdef CONFIG_BLK_DEV_IDEPCI + /* ignore MasterAbort for ide probing... */ + if (irq == TX4927_IRQ_IRC_PCIERR && + ((tx4927_pcicptr->pcistatus >> 16) & 0xf900) == + PCI_STATUS_REC_MASTER_ABORT) { + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + + return; + } +#endif + printk("PCI error interrupt (irq 0x%x).\n", irq); + + printk("pcistat:%04x, g2pstatus:%08lx, pcicstatus:%08lx\n", + (unsigned short) (tx4927_pcicptr->pcistatus >> 16), + tx4927_pcicptr->g2pstatus, tx4927_pcicptr->pcicstatus); + printk("ccfg:%08lx, tear:%02lx_%08lx\n", + (unsigned long) tx4927_ccfgptr->ccfg, + (unsigned long) (tx4927_ccfgptr->tear >> 32), + (unsigned long) tx4927_ccfgptr->tear); + show_regs(regs); +} + +void __init toshiba_rbtx4927_pci_irq_init(void) +{ + return; +} + +void tx4927_reset_pci_pcic(void) +{ + /* Reset PCI Bus */ + *tx4927_pcireset_ptr = 1; + /* Reset PCIC */ + tx4927_ccfgptr->clkctr |= TX4927_CLKCTR_PCIRST; + udelay(10000); + /* clear PCIC reset */ + tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; + *tx4927_pcireset_ptr = 0; +} +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_PCI +void print_pci_status(void) +{ + printk("PCI STATUS %lx\n", tx4927_pcicptr->pcistatus); + printk("PCIC STATUS %lx\n", tx4927_pcicptr->pcicstatus); +} + +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 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); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) + +static int __init tx4927_pcibios_init(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; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "-\n"); + + 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; + char *s = " sb/isa --"; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + 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); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xe1 = 0x%02x\n", s, v08_e1); + + /* serial irq control */ + v08_64 = 0xd0; + + /* serial irq pin */ + v32_b0 |= 0x00010000; + + /* ide irq on isa14 */ + v08_e1 &= 0xf0; + v08_e1 |= 0x0d; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xe1 = 0x%02x\n", s, v08_e1); + + 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); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + 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); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xe1 = 0x%02x\n", s, v08_e1); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + if (id == 0x91301055) { + u8 v08_04; + u8 v08_09; + u8 v08_41; + u8 v08_43; + u8 v08_5c; + char *s = " sb/ide --"; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + 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); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x5c = 0x%02x\n", s, 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; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x5c = 0x%02x\n", s, v08_5c); + + 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); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + 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); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x5c = 0x%02x\n", s, v08_5c); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + } + + register_pci_controller(&tx4927_controller); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "+\n"); + + return 0; +} + +arch_initcall(tx4927_pcibios_init); + +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +void tx4927_pci_setup(void) +{ + static int called = 0; + extern unsigned int tx4927_get_mem_size(void); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "-\n"); + + mips_memory_upper = tx4927_get_mem_size() << 20; + mips_memory_upper += KSEG0; + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_memory_upper\n", + mips_memory_upper); + 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; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_base\n", + mips_pci_io_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_size\n", + mips_pci_io_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_base\n", + mips_pci_mem_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_size\n", + mips_pci_mem_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.start\n", + pci_io_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.end\n", + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.start\n", + pci_mem_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.end\n", + pci_mem_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_io_port_base", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_io_resource to 0x%08lx 0x%08lx\n", + pci_io_resource.start, + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_mem_resource to 0x%08lx 0x%08lx\n", + pci_mem_resource.start, + pci_mem_resource.end); + + if (!called) { + printk + ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + (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; + 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 { + int pciclk = 0; + int pciclk_setting = *tx4927_pci_clk_ptr; + switch (pciclk_setting & TX4927_PCI_CLK_MASK) { + case TX4927_PCI_CLK_33: + pciclk = 33333333; + break; + case TX4927_PCI_CLK_25: + pciclk = 25000000; + break; + case TX4927_PCI_CLK_66: + pciclk = 66666666; + break; + case TX4927_PCI_CLK_50: + pciclk = 50000000; + break; + } + printk("External(%dMHz)", pciclk / 1000000); + } + 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; +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-PCIC-BUG: P2GM1PUBASE must be 0 + * if P2GM0PUBASE was 0. + */ + tx4927_pcicptr->p2gm1pubase = 0; +#else + tx4927_pcicptr->p2gm1pubase = 0xffffffff; +#endif + 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; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + ":pci setup complete:\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "+\n"); +} + +#endif /* CONFIG_PCI */ + +void toshiba_rbtx4927_restart(char *command) +{ + printk(KERN_NOTICE "System Rebooting...\n"); + + /* enable the s/w reset register */ + reg_wr08(RBTX4927_SW_RESET_ENABLE, RBTX4927_SW_RESET_ENABLE_SET); + + /* wait for enable to be seen */ + while ((reg_rd08(RBTX4927_SW_RESET_ENABLE) & + RBTX4927_SW_RESET_ENABLE_SET) == 0x00); + + /* do a s/w reset */ + reg_wr08(RBTX4927_SW_RESET_DO, RBTX4927_SW_RESET_DO_SET); + + /* do something passive while waiting for reset */ + local_irq_disable(); + while (1) + asm_wait(); + + /* no return */ +} + + +void toshiba_rbtx4927_halt(void) +{ + printk(KERN_NOTICE "System Halted\n"); + local_irq_disable(); + while (1) { + asm_wait(); + } + /* no return */ +} + +void toshiba_rbtx4927_power_off(void) +{ + toshiba_rbtx4927_halt(); + /* no return */ +} + +void __init toshiba_rbtx4927_setup(void) +{ + vu32 cp0_config; + char *argptr; + + printk("CPU is %s\n", toshiba_name); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "-\n"); + + /* f/w leaves this on at startup */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Clearing STO_ERL.\n"); + clear_c0_status(ST0_ERL); + + /* enable caches -- HCP5 does this, pmon does not */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Enabling TX49_CONF_IC,TX49_CONF_DC.\n"); + cp0_config = read_c0_config(); + cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); + write_c0_config(cp0_config); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + extern void dump_cp0(char *); + dump_cp0("toshiba_rbtx4927_early_fw_fixup"); + } +#endif + + /* setup irq stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 pic.\n"); + TX4927_WR(0xff1ff604, 0x00000400); /* irq trigger */ + TX4927_WR(0xff1ff608, 0x00000000); /* irq trigger */ + + /* setup serial stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 sio.\n"); + TX4927_WR(0xff1ff314, 0x00000000); /* h/w flow control off */ + TX4927_WR(0xff1ff414, 0x00000000); /* h/w flow control off */ + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); + + set_io_port_base(KSEG1 + TBTX4927_ISA_IO_OFFSET); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":mips_io_port_base=0x%08lx\n", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Resource\n"); + ioport_resource.end = 0xffffffff; + iomem_resource.end = 0xffffffff; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":ResetRoutines\n"); + _machine_restart = toshiba_rbtx4927_restart; + _machine_halt = toshiba_rbtx4927_halt; + _machine_power_off = toshiba_rbtx4927_power_off; + +#ifdef CONFIG_PCI + + /* PCIC */ + /* + * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. + * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1). + * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) + * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) + * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) + * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) + * i.e. S9[3]: ON (83MHz), OFF (100MHz) + */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "ccfg is %lx, DIV is %x\n", + (unsigned long) tx4927_ccfgptr-> + ccfg, TX4927_CCFG_PCIDIVMODE_MASK); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCI66, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIMIDE, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCIDIVMODE is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK); + + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + case TX4927_CCFG_PCIDIVMODE_5: + tx4927_cpu_clock = 166000000; /* 166MHz */ + break; + default: + tx4927_cpu_clock = 200000000; /* 200MHz */ + } + + /* CCFG */ + /* enable Timeout BusError */ + if (tx4927_ccfg_toeon) + tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; + + /* SDRAMC fixup */ +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-BUG: INF 01-01-18/ BUG 01-01-22 + * G-bus timeout error detection is incorrect + */ + if (tx4927_ccfg_toeon) + tx4927_sdramcptr->tr |= 0x02000000; /* RCD:3tck */ +#endif + + 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) { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=yes\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_init()\n"); + smsc_fdc37m81x_init(0x3f0); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_beg()\n"); + smsc_fdc37m81x_config_beg(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_set(KBD)\n"); + 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(); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_end()\n"); + } else { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=not_found\n"); + } + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, ":fpcibo=no\n"); + } +#endif + +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_SERIAL_TXX9_CONSOLE + argptr = prom_getcmdline(); + if (strstr(argptr, "console=") == NULL) { + strcat(argptr, " console=ttyS0,38400"); + } +#endif + +#ifdef CONFIG_ROOT_NFS + argptr = prom_getcmdline(); + if (strstr(argptr, "root=") == NULL) { + strcat(argptr, " root=/dev/nfs rw"); + } +#endif + + +#ifdef CONFIG_IP_PNP + argptr = prom_getcmdline(); + if (strstr(argptr, "ip=") == NULL) { + strcat(argptr, " ip=any"); + } +#endif + + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); +} + +#ifdef CONFIG_RTC_DS1742 +extern unsigned long rtc_ds1742_get_time(void); +extern int rtc_ds1742_set_time(unsigned long); +extern void rtc_ds1742_wait(void); +#endif + +void __init +toshiba_rbtx4927_time_init(void) +{ + u32 c1; + u32 c2; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n"); + +#ifdef CONFIG_RTC_DS1742 + + rtc_get_time = rtc_ds1742_get_time; + rtc_set_time = rtc_ds1742_set_time; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()-\n"); + rtc_ds1742_init(0xbc010000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()+\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_hpt_frequency-\n"); + rtc_ds1742_wait(); + + /* get the count */ + c1 = read_c0_count(); + + /* wait for the seconds to change again */ + rtc_ds1742_wait(); + + /* get the count again */ + c2 = read_c0_count(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_hpt_frequency+\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c1=%12u\n", c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c2=%12u\n", c2); + + /* this diff is as close as we are going to get to counter ticks per sec */ + mips_hpt_frequency = abs(c2 - c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f1=%12u\n", mips_hpt_frequency); + + /* round to 1/10th of a MHz */ + mips_hpt_frequency /= (100 * 1000); + mips_hpt_frequency *= (100 * 1000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f2=%12u\n", mips_hpt_frequency); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_INFO, + ":mips_hpt_frequency=%uHz (%uMHz)\n", + mips_hpt_frequency, + mips_hpt_frequency / 1000000); +#else + mips_hpt_frequency = 100000000; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); + +} + +void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq) +{ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "-\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "+\n"); +} |