aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/gt64120/wrppmc
diff options
context:
space:
mode:
authorMark.Zhan <rongkai.zhan@windriver.com>2006-05-06 05:04:20 -0400
committerRalf Baechle <ralf@linux-mips.org>2006-06-19 12:39:18 -0400
commita240a469649eaab03f0c4c7fbb21ea5041bf5572 (patch)
tree71801adbf35a8a449a76398a4a5d7c34066313b4 /arch/mips/gt64120/wrppmc
parenta643d2b57403dc943fd4d9a3c803addd1c6b0ddc (diff)
[MIPS] Wind River 4KC PPMC Eval Board Support
Support for the GT-64120-based Wind River 4KC PPMC Evaluation board. Signed-off-by: Rongkai.Zhan <Rongkai.zhan@windriver.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/gt64120/wrppmc')
-rw-r--r--arch/mips/gt64120/wrppmc/Makefile14
-rw-r--r--arch/mips/gt64120/wrppmc/int-handler.S59
-rw-r--r--arch/mips/gt64120/wrppmc/irq.c63
-rw-r--r--arch/mips/gt64120/wrppmc/pci.c53
-rw-r--r--arch/mips/gt64120/wrppmc/reset.c50
-rw-r--r--arch/mips/gt64120/wrppmc/setup.c173
-rw-r--r--arch/mips/gt64120/wrppmc/time.c57
7 files changed, 469 insertions, 0 deletions
diff --git a/arch/mips/gt64120/wrppmc/Makefile b/arch/mips/gt64120/wrppmc/Makefile
new file mode 100644
index 000000000000..72606b9af12a
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/Makefile
@@ -0,0 +1,14 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright 2006 Wind River System, Inc.
7# Author: Rongkai.Zhan <rongkai.zhan@windriver.com>
8#
9# Makefile for the Wind River MIPS 4KC PPMC Eval Board
10#
11
12obj-y += int-handler.o irq.o reset.o setup.o time.o pci.o
13
14EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/gt64120/wrppmc/int-handler.S b/arch/mips/gt64120/wrppmc/int-handler.S
new file mode 100644
index 000000000000..edee7b394175
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/int-handler.S
@@ -0,0 +1,59 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
7 * Copyright (C) Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com>
8 */
9#include <asm/asm.h>
10#include <asm/mipsregs.h>
11#include <asm/addrspace.h>
12#include <asm/regdef.h>
13#include <asm/stackframe.h>
14#include <asm/mach-wrppmc/mach-gt64120.h>
15
16 .align 5
17 .set noat
18NESTED(handle_IRQ, PT_SIZE, sp)
19 SAVE_ALL
20 CLI # Important: mark KERNEL mode !
21 .set at
22
23 mfc0 t0, CP0_CAUSE # get pending interrupts
24 mfc0 t1, CP0_STATUS # get enabled interrupts
25 and t0, t0, t1 # get allowed interrupts
26 andi t0, t0, 0xFF00
27 beqz t0, 1f
28 move a1, sp # Prepare 'struct pt_regs *regs' pointer
29
30 andi t1, t0, CAUSEF_IP7 # CPU Compare/Count internal timer
31 bnez t1, handle_cputimer_irq
32 andi t1, t0, CAUSEF_IP6 # UART 16550 port
33 bnez t1, handle_uart_irq
34 andi t1, t0, CAUSEF_IP3 # PCI INT_A
35 bnez t1, handle_pci_intA_irq
36
37 /* wrong alarm or masked ... */
381: j spurious_interrupt
39 nop
40END(handle_IRQ)
41
42 .align 5
43handle_cputimer_irq:
44 li a0, WRPPMC_MIPS_TIMER_IRQ
45 jal do_IRQ
46 j ret_from_irq
47
48 .align 5
49handle_uart_irq:
50 li a0, WRPPMC_UART16550_IRQ
51 jal do_IRQ
52 j ret_from_irq
53
54 .align 5
55handle_pci_intA_irq:
56 li a0, WRPPMC_PCI_INTA_IRQ
57 jal do_IRQ
58 j ret_from_irq
59
diff --git a/arch/mips/gt64120/wrppmc/irq.c b/arch/mips/gt64120/wrppmc/irq.c
new file mode 100644
index 000000000000..8605687e24ed
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/irq.c
@@ -0,0 +1,63 @@
1/*
2 * irq.c: GT64120 Interrupt Controller
3 *
4 * Copyright (C) 2006, Wind River System Inc.
5 * Author: Rongkai.Zhan, <rongkai.zhan@windriver.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12#include <linux/errno.h>
13#include <linux/init.h>
14#include <linux/kernel_stat.h>
15#include <linux/module.h>
16#include <linux/signal.h>
17#include <linux/sched.h>
18#include <linux/types.h>
19#include <linux/interrupt.h>
20#include <linux/ioport.h>
21#include <linux/timex.h>
22#include <linux/slab.h>
23#include <linux/random.h>
24#include <linux/bitops.h>
25#include <asm/bootinfo.h>
26#include <asm/io.h>
27#include <asm/bitops.h>
28#include <asm/mipsregs.h>
29#include <asm/system.h>
30#include <asm/irq_cpu.h>
31#include <asm/gt64120.h>
32
33extern asmlinkage void handle_IRQ(void);
34
35/**
36 * Initialize GT64120 Interrupt Controller
37 */
38void gt64120_init_pic(void)
39{
40 /* clear CPU Interrupt Cause Registers */
41 GT_WRITE(GT_INTRCAUSE_OFS, (0x1F << 21));
42 GT_WRITE(GT_HINTRCAUSE_OFS, 0x00);
43
44 /* Disable all interrupts from GT64120 bridge chip */
45 GT_WRITE(GT_INTRMASK_OFS, 0x00);
46 GT_WRITE(GT_HINTRMASK_OFS, 0x00);
47 GT_WRITE(GT_PCI0_ICMASK_OFS, 0x00);
48 GT_WRITE(GT_PCI0_HICMASK_OFS, 0x00);
49}
50
51void __init arch_init_irq(void)
52{
53 /* enable all CPU interrupt bits. */
54 set_c0_status(ST0_IM); /* IE bit is still 0 */
55
56 /* Install MIPS Interrupt Trap Vector */
57 set_except_vector(0, handle_IRQ);
58
59 /* IRQ 0 - 7 are for MIPS common irq_cpu controller */
60 mips_cpu_irq_init(0);
61
62 gt64120_init_pic();
63}
diff --git a/arch/mips/gt64120/wrppmc/pci.c b/arch/mips/gt64120/wrppmc/pci.c
new file mode 100644
index 000000000000..2fbe93467f78
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/pci.c
@@ -0,0 +1,53 @@
1/*
2 * pci.c: GT64120 PCI support.
3 *
4 * Copyright (C) 2006, Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/init.h>
11#include <linux/types.h>
12#include <linux/pci.h>
13#include <linux/kernel.h>
14#include <asm/gt64120.h>
15
16extern struct pci_ops gt64120_pci_ops;
17
18static struct resource pci0_io_resource = {
19 .name = "pci_0 io",
20 .start = GT_PCI_IO_BASE,
21 .end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1,
22 .flags = IORESOURCE_IO,
23};
24
25static struct resource pci0_mem_resource = {
26 .name = "pci_0 memory",
27 .start = GT_PCI_MEM_BASE,
28 .end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1,
29 .flags = IORESOURCE_MEM,
30};
31
32static struct pci_controller hose_0 = {
33 .pci_ops = &gt64120_pci_ops,
34 .io_resource = &pci0_io_resource,
35 .mem_resource = &pci0_mem_resource,
36};
37
38static int __init gt64120_pci_init(void)
39{
40 u32 tmp;
41
42 tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */
43 tmp = GT_READ(GT_PCI0_BARE_OFS);
44
45 /* reset the whole PCI I/O space range */
46 ioport_resource.start = GT_PCI_IO_BASE;
47 ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
48
49 register_pci_controller(&hose_0);
50 return 0;
51}
52
53arch_initcall(gt64120_pci_init);
diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/gt64120/wrppmc/reset.c
new file mode 100644
index 000000000000..b97039c6d3db
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/reset.c
@@ -0,0 +1,50 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1997 Ralf Baechle
7 */
8#include <linux/sched.h>
9#include <linux/mm.h>
10#include <asm/io.h>
11#include <asm/pgtable.h>
12#include <asm/processor.h>
13#include <asm/reboot.h>
14#include <asm/system.h>
15#include <asm/cacheflush.h>
16
17void wrppmc_machine_restart(char *command)
18{
19 /*
20 * Ouch, we're still alive ... This time we take the silver bullet ...
21 * ... and find that we leave the hardware in a state in which the
22 * kernel in the flush locks up somewhen during of after the PCI
23 * detection stuff.
24 */
25 local_irq_disable();
26 set_c0_status(ST0_BEV | ST0_ERL);
27 change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
28 flush_cache_all();
29 write_c0_wired(0);
30 __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
31}
32
33void wrppmc_machine_halt(void)
34{
35 local_irq_disable();
36
37 printk(KERN_NOTICE "You can safely turn off the power\n");
38 while (1) {
39 __asm__(
40 ".set\tmips3\n\t"
41 "wait\n\t"
42 ".set\tmips0"
43 );
44 }
45}
46
47void wrppmc_machine_power_off(void)
48{
49 wrppmc_machine_halt();
50}
diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/gt64120/wrppmc/setup.c
new file mode 100644
index 000000000000..20c591e49dae
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/setup.c
@@ -0,0 +1,173 @@
1/*
2 * setup.c: Setup pointers to hardware dependent routines.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
9 * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com>
10 */
11#include <linux/config.h>
12#include <linux/init.h>
13#include <linux/string.h>
14#include <linux/kernel.h>
15#include <linux/tty.h>
16#include <linux/serial.h>
17#include <linux/serial_core.h>
18#include <linux/pm.h>
19
20#include <asm/io.h>
21#include <asm/bootinfo.h>
22#include <asm/reboot.h>
23#include <asm/time.h>
24#include <asm/gt64120.h>
25
26unsigned long gt64120_base = KSEG1ADDR(0x14000000);
27
28#ifdef WRPPMC_EARLY_DEBUG
29
30static volatile unsigned char * wrppmc_led = \
31 (volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE);
32
33/*
34 * PPMC LED control register:
35 * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON)
36 * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON)
37 * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON)
38 */
39void wrppmc_led_on(int mask)
40{
41 unsigned char value = *wrppmc_led;
42
43 value &= (0xF8 | mask);
44 *wrppmc_led = value;
45}
46
47/* If mask = 0, turn off all LEDs */
48void wrppmc_led_off(int mask)
49{
50 unsigned char value = *wrppmc_led;
51
52 value |= (0x7 & mask);
53 *wrppmc_led = value;
54}
55
56/*
57 * We assume that bootloader has initialized UART16550 correctly
58 */
59void __init wrppmc_early_putc(char ch)
60{
61 static volatile unsigned char *wrppmc_uart = \
62 (volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE);
63 unsigned char value;
64
65 /* Wait until Transmit-Holding-Register is empty */
66 while (1) {
67 value = *(wrppmc_uart + 5);
68 if (value & 0x20)
69 break;
70 }
71
72 *wrppmc_uart = ch;
73}
74
75void __init wrppmc_early_printk(const char *fmt, ...)
76{
77 static char pbuf[256] = {'\0', };
78 char *ch = pbuf;
79 va_list args;
80 unsigned int i;
81
82 memset(pbuf, 0, 256);
83 va_start(args, fmt);
84 i = vsprintf(pbuf, fmt, args);
85 va_end(args);
86
87 /* Print the string */
88 while (*ch != '\0') {
89 wrppmc_early_putc(*ch);
90 /* if print '\n', also print '\r' */
91 if (*ch++ == '\n')
92 wrppmc_early_putc('\r');
93 }
94}
95#endif /* WRPPMC_EARLY_DEBUG */
96
97unsigned long __init prom_free_prom_memory(void)
98{
99 return 0;
100}
101
102#ifdef CONFIG_SERIAL_8250
103static void wrppmc_setup_serial(void)
104{
105 struct uart_port up;
106
107 memset(&up, 0x00, sizeof(struct uart_port));
108
109 /*
110 * A note about mapbase/membase
111 * -) mapbase is the physical address of the IO port.
112 * -) membase is an 'ioremapped' cookie.
113 */
114 up.line = 0;
115 up.type = PORT_16550;
116 up.iotype = UPIO_MEM;
117 up.mapbase = WRPPMC_UART16550_BASE;
118 up.membase = ioremap(up.mapbase, 8);
119 up.irq = WRPPMC_UART16550_IRQ;
120 up.uartclk = WRPPMC_UART16550_CLOCK;
121 up.flags = UPF_SKIP_TEST/* | UPF_BOOT_AUTOCONF */;
122 up.regshift = 0;
123
124 early_serial_setup(&up);
125}
126#endif
127
128void __init plat_setup(void)
129{
130 extern void wrppmc_time_init(void);
131 extern void wrppmc_timer_setup(struct irqaction *);
132 extern void wrppmc_machine_restart(char *command);
133 extern void wrppmc_machine_halt(void);
134 extern void wrppmc_machine_power_off(void);
135
136 _machine_restart = wrppmc_machine_restart;
137 _machine_halt = wrppmc_machine_halt;
138 pm_power_off = wrppmc_machine_power_off;
139
140 /* Use MIPS Count/Compare Timer */
141 board_time_init = wrppmc_time_init;
142 board_timer_setup = wrppmc_timer_setup;
143
144 /* This makes the operations of 'in/out[bwl]' to the
145 * physical address ( < KSEG0) can work via KSEG1
146 */
147 set_io_port_base(KSEG1);
148
149#ifdef CONFIG_SERIAL_8250
150 wrppmc_setup_serial();
151#endif
152}
153
154const char *get_system_type(void)
155{
156 return "Wind River PPMC (GT64120)";
157}
158
159/*
160 * Initializes basic routines and structures pointers, memory size (as
161 * given by the bios and saves the command line.
162 */
163void __init prom_init(void)
164{
165 mips_machgroup = MACH_GROUP_GALILEO;
166 mips_machtype = MACH_EV64120A;
167
168 add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
169 add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
170
171 wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n",
172 WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE));
173}
diff --git a/arch/mips/gt64120/wrppmc/time.c b/arch/mips/gt64120/wrppmc/time.c
new file mode 100644
index 000000000000..175d22adb450
--- /dev/null
+++ b/arch/mips/gt64120/wrppmc/time.c
@@ -0,0 +1,57 @@
1/*
2 * time.c: MIPS CPU Count/Compare timer hookup
3 *
4 * Author: Mark.Zhan, <rongkai.zhan@windriver.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
11 * Copyright (C) 2006, Wind River System Inc.
12 */
13#include <linux/config.h>
14#include <linux/init.h>
15#include <linux/string.h>
16#include <linux/kernel.h>
17#include <linux/param.h> /* for HZ */
18#include <linux/irq.h>
19#include <linux/timex.h>
20#include <linux/interrupt.h>
21
22#include <asm/reboot.h>
23#include <asm/time.h>
24#include <asm/io.h>
25#include <asm/bootinfo.h>
26#include <asm/gt64120.h>
27
28#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */
29
30void __init wrppmc_timer_setup(struct irqaction *irq)
31{
32 /* Install ISR for timer interrupt */
33 setup_irq(WRPPMC_MIPS_TIMER_IRQ, irq);
34
35 /* to generate the first timer interrupt */
36 write_c0_compare(mips_hpt_frequency/HZ);
37 write_c0_count(0);
38}
39
40/*
41 * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
42 *
43 * NOTE: We disable all GT64120 timers, and use MIPS processor internal
44 * timer as the source of kernel clock tick.
45 */
46void __init wrppmc_time_init(void)
47{
48 /* Disable GT64120 timers */
49 GT_WRITE(GT_TC_CONTROL_OFS, 0x00);
50 GT_WRITE(GT_TC0_OFS, 0x00);
51 GT_WRITE(GT_TC1_OFS, 0x00);
52 GT_WRITE(GT_TC2_OFS, 0x00);
53 GT_WRITE(GT_TC3_OFS, 0x00);
54
55 /* Use MIPS compare/count internal timer */
56 mips_hpt_frequency = WRPPMC_CPU_CLK_FREQ;
57}