diff options
Diffstat (limited to 'arch/mips/mips-boards/atlas')
-rw-r--r-- | arch/mips/mips-boards/atlas/Makefile | 20 | ||||
-rw-r--r-- | arch/mips/mips-boards/atlas/atlas_gdb.c | 97 | ||||
-rw-r--r-- | arch/mips/mips-boards/atlas/atlas_int.c | 142 | ||||
-rw-r--r-- | arch/mips/mips-boards/atlas/atlas_setup.c | 95 |
4 files changed, 354 insertions, 0 deletions
diff --git a/arch/mips/mips-boards/atlas/Makefile b/arch/mips/mips-boards/atlas/Makefile new file mode 100644 index 000000000000..d8dab75906bf --- /dev/null +++ b/arch/mips/mips-boards/atlas/Makefile @@ -0,0 +1,20 @@ +# +# Carsten Langgaard, carstenl@mips.com +# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. +# +# This program is free software; you can distribute it and/or modify it +# under the terms of the GNU General Public License (Version 2) as +# published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# 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., +# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# + +obj-y := atlas_int.o atlas_setup.o +obj-$(CONFIG_KGDB) += atlas_gdb.o diff --git a/arch/mips/mips-boards/atlas/atlas_gdb.c b/arch/mips/mips-boards/atlas/atlas_gdb.c new file mode 100644 index 000000000000..fb65280f1780 --- /dev/null +++ b/arch/mips/mips-boards/atlas/atlas_gdb.c @@ -0,0 +1,97 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * 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., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * This is the interface to the remote debugger stub. + */ +#include <asm/io.h> +#include <asm/mips-boards/atlas.h> +#include <asm/mips-boards/saa9730_uart.h> + +#define INB(a) inb((unsigned long)a) +#define OUTB(x,a) outb(x,(unsigned long)a) + +/* + * This is the interface to the remote debugger stub + * if the Philips part is used for the debug port, + * called from the platform setup code. + */ +void *saa9730_base = (void *)ATLAS_SAA9730_REG; + +static int saa9730_kgdb_active = 0; + +#define SAA9730_BAUDCLOCK(baud) (((ATLAS_SAA9730_BAUDCLOCK/(baud))/16)-1) + +int saa9730_kgdb_hook(int speed) +{ + int baudclock; + t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); + + /* + * Clear all interrupts + */ + (void) INB(&kgdb_uart->Lsr); + (void) INB(&kgdb_uart->Msr); + (void) INB(&kgdb_uart->Thr_Rbr); + (void) INB(&kgdb_uart->Iir_Fcr); + + /* + * Now, initialize the UART + */ + /* 8 data bits, one stop bit, no parity */ + OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr); + + baudclock = SAA9730_BAUDCLOCK(speed); + + OUTB((baudclock >> 16) & 0xff, &kgdb_uart->BaudDivMsb); + OUTB( baudclock & 0xff, &kgdb_uart->BaudDivLsb); + + /* Set RTS/DTR active */ + OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr); + saa9730_kgdb_active = 1; + + return speed; +} + +int saa9730_putDebugChar(char c) +{ + t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); + + if (!saa9730_kgdb_active) { /* need to init device first */ + return 0; + } + + while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE)) + ; + OUTB(c, &kgdb_uart->Thr_Rbr); + + return 1; +} + +char saa9730_getDebugChar(void) +{ + t_uart_saa9730_regmap *kgdb_uart = (t_uart_saa9730_regmap *)(saa9730_base + SAA9730_UART_REGS_ADDR); + char c; + + if (!saa9730_kgdb_active) { /* need to init device first */ + return 0; + } + while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR)) + ; + + c = INB(&kgdb_uart->Thr_Rbr); + return(c); +} diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c new file mode 100644 index 000000000000..8f1d875217a2 --- /dev/null +++ b/arch/mips/mips-boards/atlas/atlas_int.c @@ -0,0 +1,142 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * 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., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Routines for generic manipulation of the interrupts found on the MIPS + * Atlas board. + * + */ +#include <linux/compiler.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> + +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/mips-boards/atlas.h> +#include <asm/mips-boards/atlasint.h> +#include <asm/gdb-stub.h> + + +static struct atlas_ictrl_regs *atlas_hw0_icregs; + +extern asmlinkage void mipsIRQ(void); + +#if 0 +#define DEBUG_INT(x...) printk(x) +#else +#define DEBUG_INT(x...) +#endif + +void disable_atlas_irq(unsigned int irq_nr) +{ + atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE)); + iob(); +} + +void enable_atlas_irq(unsigned int irq_nr) +{ + atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE)); + iob(); +} + +static unsigned int startup_atlas_irq(unsigned int irq) +{ + enable_atlas_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_atlas_irq disable_atlas_irq + +#define mask_and_ack_atlas_irq disable_atlas_irq + +static void end_atlas_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_atlas_irq(irq); +} + +static struct hw_interrupt_type atlas_irq_type = { + "Atlas", + startup_atlas_irq, + shutdown_atlas_irq, + enable_atlas_irq, + disable_atlas_irq, + mask_and_ack_atlas_irq, + end_atlas_irq, + NULL +}; + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +void atlas_hw0_irqdispatch(struct pt_regs *regs) +{ + unsigned long int_status; + int irq; + + int_status = atlas_hw0_icregs->intstatus; + + /* if int_status == 0, then the interrupt has already been cleared */ + if (unlikely(int_status == 0)) + return; + + irq = ATLASINT_BASE + ls1bit32(int_status); + + DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); + + do_IRQ(irq, regs); +} + +void __init arch_init_irq(void) +{ + int i; + + atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *)); + + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. + */ + atlas_hw0_icregs->intrsten = 0xffffffff; + + /* Now safe to set the exception vector. */ + set_except_vector(0, mipsIRQ); + + for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &atlas_irq_type; + spin_lock_init(&irq_desc[i].lock); + } +} diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c new file mode 100644 index 000000000000..0a1dd9bbc02e --- /dev/null +++ b/arch/mips/mips-boards/atlas/atlas_setup.c @@ -0,0 +1,95 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * 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., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/tty.h> +#include <linux/serial.h> +#include <linux/serial_core.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mips-boards/generic.h> +#include <asm/mips-boards/prom.h> +#include <asm/mips-boards/atlas.h> +#include <asm/mips-boards/atlasint.h> +#include <asm/time.h> +#include <asm/traps.h> + +extern void mips_reboot_setup(void); +extern void mips_time_init(void); +extern void mips_timer_setup(struct irqaction *irq); +extern unsigned long mips_rtc_get_time(void); + +#ifdef CONFIG_KGDB +extern void kgdb_config(void); +#endif + +static void __init serial_init(void); + +const char *get_system_type(void) +{ + return "MIPS Atlas"; +} + +static int __init atlas_setup(void) +{ + ioport_resource.end = 0x7fffffff; + + serial_init (); + +#ifdef CONFIG_KGDB + kgdb_config(); +#endif + mips_reboot_setup(); + + board_time_init = mips_time_init; + board_timer_setup = mips_timer_setup; + rtc_get_time = mips_rtc_get_time; + + return 0; +} + +early_initcall(atlas_setup); + +static void __init serial_init(void) +{ +#ifdef CONFIG_SERIAL_8250 + struct uart_port s; + + memset(&s, 0, sizeof(s)); + +#ifdef CONFIG_CPU_LITTLE_ENDIAN + s.iobase = ATLAS_UART_REGS_BASE; +#else + s.iobase = ATLAS_UART_REGS_BASE+3; +#endif + s.irq = ATLASINT_UART; + s.uartclk = ATLAS_BASE_BAUD * 16; + s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; + s.iotype = SERIAL_IO_PORT; + s.regshift = 3; + + if (early_serial_setup(&s) != 0) { + printk(KERN_ERR "Serial setup failed!\n"); + } +#endif +} |