diff options
Diffstat (limited to 'arch/mips/wrppmc')
-rw-r--r-- | arch/mips/wrppmc/Makefile | 12 | ||||
-rw-r--r-- | arch/mips/wrppmc/Platform | 7 | ||||
-rw-r--r-- | arch/mips/wrppmc/irq.c | 56 | ||||
-rw-r--r-- | arch/mips/wrppmc/pci.c | 54 | ||||
-rw-r--r-- | arch/mips/wrppmc/reset.c | 40 | ||||
-rw-r--r-- | arch/mips/wrppmc/serial.c | 80 | ||||
-rw-r--r-- | arch/mips/wrppmc/setup.c | 128 | ||||
-rw-r--r-- | arch/mips/wrppmc/time.c | 39 |
8 files changed, 416 insertions, 0 deletions
diff --git a/arch/mips/wrppmc/Makefile b/arch/mips/wrppmc/Makefile new file mode 100644 index 0000000..307cc69 --- /dev/null +++ b/arch/mips/wrppmc/Makefile @@ -0,0 +1,12 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright 2006 Wind River System, Inc. +# Author: Rongkai.Zhan <rongkai.zhan@windriver.com> +# +# Makefile for the Wind River MIPS 4Kc PPMC Eval Board +# + +obj-y += irq.o pci.o reset.o serial.o setup.o time.o diff --git a/arch/mips/wrppmc/Platform b/arch/mips/wrppmc/Platform new file mode 100644 index 0000000..e758645 --- /dev/null +++ b/arch/mips/wrppmc/Platform @@ -0,0 +1,7 @@ +# +# Wind River PPMC Board (4KC + GT64120) +# +platform-$(CONFIG_WR_PPMC) += wrppmc/ +cflags-$(CONFIG_WR_PPMC) += \ + -I$(srctree)/arch/mips/include/asm/mach-wrppmc +load-$(CONFIG_WR_PPMC) += 0xffffffff80100000 diff --git a/arch/mips/wrppmc/irq.c b/arch/mips/wrppmc/irq.c new file mode 100644 index 0000000..c6e7062 --- /dev/null +++ b/arch/mips/wrppmc/irq.c @@ -0,0 +1,56 @@ +/* + * irq.c: GT64120 Interrupt Controller + * + * Copyright (C) 2006, Wind River System Inc. + * Author: Rongkai.Zhan, <rongkai.zhan@windriver.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. + */ +#include <linux/hardirq.h> +#include <linux/init.h> +#include <linux/irq.h> + +#include <asm/gt64120.h> +#include <asm/irq_cpu.h> +#include <asm/mipsregs.h> + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; + + if (pending & STATUSF_IP7) + do_IRQ(WRPPMC_MIPS_TIMER_IRQ); /* CPU Compare/Count internal timer */ + else if (pending & STATUSF_IP6) + do_IRQ(WRPPMC_UART16550_IRQ); /* UART 16550 port */ + else if (pending & STATUSF_IP3) + do_IRQ(WRPPMC_PCI_INTA_IRQ); /* PCI INT_A */ + else + spurious_interrupt(); +} + +/** + * Initialize GT64120 Interrupt Controller + */ +void gt64120_init_pic(void) +{ + /* clear CPU Interrupt Cause Registers */ + GT_WRITE(GT_INTRCAUSE_OFS, (0x1F << 21)); + GT_WRITE(GT_HINTRCAUSE_OFS, 0x00); + + /* Disable all interrupts from GT64120 bridge chip */ + GT_WRITE(GT_INTRMASK_OFS, 0x00); + GT_WRITE(GT_HINTRMASK_OFS, 0x00); + GT_WRITE(GT_PCI0_ICMASK_OFS, 0x00); + GT_WRITE(GT_PCI0_HICMASK_OFS, 0x00); +} + +void __init arch_init_irq(void) +{ + /* IRQ 0 - 7 are for MIPS common irq_cpu controller */ + mips_cpu_irq_init(); + + gt64120_init_pic(); +} diff --git a/arch/mips/wrppmc/pci.c b/arch/mips/wrppmc/pci.c new file mode 100644 index 0000000..d06192f --- /dev/null +++ b/arch/mips/wrppmc/pci.c @@ -0,0 +1,54 @@ +/* + * pci.c: GT64120 PCI support. + * + * Copyright (C) 2006, Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/types.h> +#include <linux/pci.h> + +#include <asm/gt64120.h> + +extern struct pci_ops gt64xxx_pci0_ops; + +static struct resource pci0_io_resource = { + .name = "pci_0 io", + .start = GT_PCI_IO_BASE, + .end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO, +}; + +static struct resource pci0_mem_resource = { + .name = "pci_0 memory", + .start = GT_PCI_MEM_BASE, + .end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct pci_controller hose_0 = { + .pci_ops = >64xxx_pci0_ops, + .io_resource = &pci0_io_resource, + .mem_resource = &pci0_mem_resource, +}; + +static int __init gt64120_pci_init(void) +{ + u32 tmp; + + tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */ + tmp = GT_READ(GT_PCI0_BARE_OFS); + + /* reset the whole PCI I/O space range */ + ioport_resource.start = GT_PCI_IO_BASE; + ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; + + register_pci_controller(&hose_0); + return 0; +} + +arch_initcall(gt64120_pci_init); diff --git a/arch/mips/wrppmc/reset.c b/arch/mips/wrppmc/reset.c new file mode 100644 index 0000000..cc5474b --- /dev/null +++ b/arch/mips/wrppmc/reset.c @@ -0,0 +1,40 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997 Ralf Baechle + */ +#include <linux/irqflags.h> +#include <linux/kernel.h> + +#include <asm/cacheflush.h> +#include <asm/mipsregs.h> +#include <asm/processor.h> + +void wrppmc_machine_restart(char *command) +{ + /* + * Ouch, we're still alive ... This time we take the silver bullet ... + * ... and find that we leave the hardware in a state in which the + * kernel in the flush locks up somewhen during of after the PCI + * detection stuff. + */ + local_irq_disable(); + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); +} + +void wrppmc_machine_halt(void) +{ + local_irq_disable(); + + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) { + if (cpu_wait) + cpu_wait(); + } +} diff --git a/arch/mips/wrppmc/serial.c b/arch/mips/wrppmc/serial.c new file mode 100644 index 0000000..6f9d085 --- /dev/null +++ b/arch/mips/wrppmc/serial.c @@ -0,0 +1,80 @@ +/* + * Registration of WRPPMC UART platform device. + * + * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org> + * + * 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 program is distributed in the hope that 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/serial_8250.h> + +#include <asm/gt64120.h> + +static struct resource wrppmc_uart_resource[] __initdata = { + { + .start = WRPPMC_UART16550_BASE, + .end = WRPPMC_UART16550_BASE + 7, + .flags = IORESOURCE_MEM, + }, + { + .start = WRPPMC_UART16550_IRQ, + .end = WRPPMC_UART16550_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct plat_serial8250_port wrppmc_serial8250_port[] = { + { + .irq = WRPPMC_UART16550_IRQ, + .uartclk = WRPPMC_UART16550_CLOCK, + .iotype = UPIO_MEM, + .flags = UPF_IOREMAP | UPF_SKIP_TEST, + .mapbase = WRPPMC_UART16550_BASE, + }, + {}, +}; + +static __init int wrppmc_uart_add(void) +{ + struct platform_device *pdev; + int retval; + + pdev = platform_device_alloc("serial8250", -1); + if (!pdev) + return -ENOMEM; + + pdev->id = PLAT8250_DEV_PLATFORM; + pdev->dev.platform_data = wrppmc_serial8250_port; + + retval = platform_device_add_resources(pdev, wrppmc_uart_resource, + ARRAY_SIZE(wrppmc_uart_resource)); + if (retval) + goto err_free_device; + + retval = platform_device_add(pdev); + if (retval) + goto err_free_device; + + return 0; + +err_free_device: + platform_device_put(pdev); + + return retval; +} +device_initcall(wrppmc_uart_add); diff --git a/arch/mips/wrppmc/setup.c b/arch/mips/wrppmc/setup.c new file mode 100644 index 0000000..ca65c84 --- /dev/null +++ b/arch/mips/wrppmc/setup.c @@ -0,0 +1,128 @@ +/* + * setup.c: Setup pointers to hardware dependent routines. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com> + */ +#include <linux/init.h> +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/pm.h> + +#include <asm/io.h> +#include <asm/bootinfo.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/gt64120.h> + +unsigned long gt64120_base = KSEG1ADDR(0x14000000); + +#ifdef WRPPMC_EARLY_DEBUG + +static volatile unsigned char * wrppmc_led = \ + (volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE); + +/* + * PPMC LED control register: + * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON) + * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON) + * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON) + */ +void wrppmc_led_on(int mask) +{ + unsigned char value = *wrppmc_led; + + value &= (0xF8 | mask); + *wrppmc_led = value; +} + +/* If mask = 0, turn off all LEDs */ +void wrppmc_led_off(int mask) +{ + unsigned char value = *wrppmc_led; + + value |= (0x7 & mask); + *wrppmc_led = value; +} + +/* + * We assume that bootloader has initialized UART16550 correctly + */ +void __init wrppmc_early_putc(char ch) +{ + static volatile unsigned char *wrppmc_uart = \ + (volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE); + unsigned char value; + + /* Wait until Transmit-Holding-Register is empty */ + while (1) { + value = *(wrppmc_uart + 5); + if (value & 0x20) + break; + } + + *wrppmc_uart = ch; +} + +void __init wrppmc_early_printk(const char *fmt, ...) +{ + static char pbuf[256] = {'\0', }; + char *ch = pbuf; + va_list args; + unsigned int i; + + memset(pbuf, 0, 256); + va_start(args, fmt); + i = vsprintf(pbuf, fmt, args); + va_end(args); + + /* Print the string */ + while (*ch != '\0') { + wrppmc_early_putc(*ch); + /* if print '\n', also print '\r' */ + if (*ch++ == '\n') + wrppmc_early_putc('\r'); + } +} +#endif /* WRPPMC_EARLY_DEBUG */ + +void __init prom_free_prom_memory(void) +{ +} + +void __init plat_mem_setup(void) +{ + extern void wrppmc_machine_restart(char *command); + extern void wrppmc_machine_halt(void); + + _machine_restart = wrppmc_machine_restart; + _machine_halt = wrppmc_machine_halt; + pm_power_off = wrppmc_machine_halt; + + /* This makes the operations of 'in/out[bwl]' to the + * physical address ( < KSEG0) can work via KSEG1 + */ + set_io_port_base(KSEG1); +} + +const char *get_system_type(void) +{ + return "Wind River PPMC (GT64120)"; +} + +/* + * Initializes basic routines and structures pointers, memory size (as + * given by the bios and saves the command line. + */ +void __init prom_init(void) +{ + add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM); + add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA); + + wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n", + WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE)); +} diff --git a/arch/mips/wrppmc/time.c b/arch/mips/wrppmc/time.c new file mode 100644 index 0000000..668dbd5 --- /dev/null +++ b/arch/mips/wrppmc/time.c @@ -0,0 +1,39 @@ +/* + * time.c: MIPS CPU Count/Compare timer hookup + * + * Author: Mark.Zhan, <rongkai.zhan@windriver.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2006, Wind River System Inc. + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> + +#include <asm/gt64120.h> +#include <asm/time.h> + +#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */ + +/* + * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect + * + * NOTE: We disable all GT64120 timers, and use MIPS processor internal + * timer as the source of kernel clock tick. + */ +void __init plat_time_init(void) +{ + /* Disable GT64120 timers */ + GT_WRITE(GT_TC_CONTROL_OFS, 0x00); + GT_WRITE(GT_TC0_OFS, 0x00); + GT_WRITE(GT_TC1_OFS, 0x00); + GT_WRITE(GT_TC2_OFS, 0x00); + GT_WRITE(GT_TC3_OFS, 0x00); + + /* Use MIPS compare/count internal timer */ + mips_hpt_frequency = WRPPMC_CPU_CLK_FREQ; +} |