PageRenderTime 40ms CodeModel.GetById 1ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/v850/kernel/as85ep1.c

https://bitbucket.org/evzijst/gittest
C | 240 lines | 157 code | 43 blank | 40 comment | 18 complexity | 818b64bceacbbf9dbf3615f1464864d1 MD5 | raw file
  1/*
  2 * arch/v850/kernel/as85ep1.c -- AS85EP1 V850E evaluation chip/board
  3 *
  4 *  Copyright (C) 2002,03  NEC Electronics Corporation
  5 *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
  6 *
  7 * This file is subject to the terms and conditions of the GNU General
  8 * Public License.  See the file COPYING in the main directory of this
  9 * archive for more details.
 10 *
 11 * Written by Miles Bader <miles@gnu.org>
 12 */
 13
 14#include <linux/config.h>
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17#include <linux/init.h>
 18#include <linux/bootmem.h>
 19#include <linux/major.h>
 20#include <linux/irq.h>
 21
 22#include <asm/machdep.h>
 23#include <asm/atomic.h>
 24#include <asm/page.h>
 25#include <asm/v850e_timer_d.h>
 26#include <asm/v850e_uart.h>
 27
 28#include "mach.h"
 29
 30
 31/* SRAM and SDRAM are vaguely contiguous (with a big hole in between; see
 32   mach_reserve_bootmem for details); use both as one big area.  */
 33#define RAM_START 	SRAM_ADDR
 34#define RAM_END		(SDRAM_ADDR + SDRAM_SIZE)
 35
 36/* The bits of this port are connected to an 8-LED bar-graph.  */
 37#define LEDS_PORT	4
 38
 39
 40static void as85ep1_led_tick (void);
 41
 42extern char _intv_copy_src_start, _intv_copy_src_end;
 43extern char _intv_copy_dst_start;
 44
 45
 46void __init mach_early_init (void)
 47{
 48#ifndef CONFIG_ROM_KERNEL
 49	const u32 *src;
 50	register u32 *dst asm ("ep");
 51#endif
 52
 53	AS85EP1_CSC(0) = 0x0403;
 54	AS85EP1_BCT(0) = 0xB8B8;
 55	AS85EP1_DWC(0) = 0x0104;
 56	AS85EP1_BCC    = 0x0012;
 57	AS85EP1_ASC    = 0;
 58	AS85EP1_LBS    = 0x00A9;
 59
 60	AS85EP1_PORT_PMC(6)  = 0xFF; /* valid A0,A1,A20-A25 */
 61	AS85EP1_PORT_PMC(7)  = 0x0E; /* valid CS1-CS3       */
 62	AS85EP1_PORT_PMC(9)  = 0xFF; /* valid D16-D23       */
 63	AS85EP1_PORT_PMC(10) = 0xFF; /* valid D24-D31       */
 64
 65	AS85EP1_RFS(1) = 0x800c;
 66	AS85EP1_RFS(3) = 0x800c;
 67	AS85EP1_SCR(1) = 0x20A9;
 68	AS85EP1_SCR(3) = 0x20A9;
 69
 70#ifndef CONFIG_ROM_KERNEL
 71	/* The early chip we have is buggy, and writing the interrupt
 72	   vectors into low RAM may screw up, so for non-ROM kernels, we
 73	   only rely on the reset vector being downloaded, and copy the
 74	   rest of the interrupt vectors into place here.  The specific bug
 75	   is that writing address N, where (N & 0x10) == 0x10, will _also_
 76	   write to address (N - 0x10).  We avoid this (effectively) by
 77	   writing in 16-byte chunks backwards from the end.  */
 78
 79	AS85EP1_IRAMM = 0x3;	/* "write-mode" for the internal instruction memory */
 80
 81	src = (u32 *)(((u32)&_intv_copy_src_end - 1) & ~0xF);
 82	dst = (u32 *)&_intv_copy_dst_start
 83		+ (src - (u32 *)&_intv_copy_src_start);
 84	do {
 85		u32 t0 = src[0], t1 = src[1], t2 = src[2], t3 = src[3];
 86		dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
 87		dst -= 4;
 88		src -= 4;
 89	} while (src > (u32 *)&_intv_copy_src_start);
 90
 91	AS85EP1_IRAMM = 0x0;	/* "read-mode" for the internal instruction memory */
 92#endif /* !CONFIG_ROM_KERNEL */
 93
 94	v850e_intc_disable_irqs ();
 95}
 96
 97void __init mach_setup (char **cmdline)
 98{
 99	AS85EP1_PORT_PMC (LEDS_PORT) = 0; /* Make the LEDs port an I/O port. */
100	AS85EP1_PORT_PM (LEDS_PORT) = 0; /* Make all the bits output pins.  */
101	mach_tick = as85ep1_led_tick;
102}
103
104void __init mach_get_physical_ram (unsigned long *ram_start,
105				   unsigned long *ram_len)
106{
107	*ram_start = RAM_START;
108	*ram_len = RAM_END - RAM_START;
109}
110
111/* Convenience macros.  */
112#define SRAM_END	(SRAM_ADDR + SRAM_SIZE)
113#define SDRAM_END	(SDRAM_ADDR + SDRAM_SIZE)
114
115void __init mach_reserve_bootmem ()
116{
117	if (SDRAM_ADDR < RAM_END && SDRAM_ADDR > RAM_START)
118		/* We can't use the space between SRAM and SDRAM, so
119		   prevent the kernel from trying.  */
120		reserve_bootmem (SRAM_END, SDRAM_ADDR - SRAM_END);
121}
122
123void mach_gettimeofday (struct timespec *tv)
124{
125	tv->tv_sec = 0;
126	tv->tv_nsec = 0;
127}
128
129void __init mach_sched_init (struct irqaction *timer_action)
130{
131	/* Start hardware timer.  */
132	v850e_timer_d_configure (0, HZ);
133	/* Install timer interrupt handler.  */
134	setup_irq (IRQ_INTCMD(0), timer_action);
135}
136
137static struct v850e_intc_irq_init irq_inits[] = {
138	{ "IRQ", 0, 		NUM_MACH_IRQS,	1, 7 },
139	{ "CCC", IRQ_INTCCC(0),	IRQ_INTCCC_NUM, 1, 5 },
140	{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM,	1, 5 },
141	{ "SRE", IRQ_INTSRE(0), IRQ_INTSRE_NUM,	3, 3 },
142	{ "SR",	 IRQ_INTSR(0),	IRQ_INTSR_NUM, 	3, 4 },
143	{ "ST",  IRQ_INTST(0), 	IRQ_INTST_NUM, 	3, 5 },
144	{ 0 }
145};
146#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
147
148static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
149
150void __init mach_init_irqs (void)
151{
152	v850e_intc_init_irq_types (irq_inits, hw_itypes);
153}
154
155void machine_restart (char *__unused)
156{
157#ifdef CONFIG_RESET_GUARD
158	disable_reset_guard ();
159#endif
160	asm ("jmp r0"); /* Jump to the reset vector.  */
161}
162
163EXPORT_SYMBOL(machine_restart);
164
165void machine_halt (void)
166{
167#ifdef CONFIG_RESET_GUARD
168	disable_reset_guard ();
169#endif
170	local_irq_disable ();	/* Ignore all interrupts.  */
171	AS85EP1_PORT_IO (LEDS_PORT) = 0xAA;	/* Note that we halted.  */
172	for (;;)
173		asm ("halt; nop; nop; nop; nop; nop");
174}
175
176EXPORT_SYMBOL(machine_halt);
177
178void machine_power_off (void)
179{
180	machine_halt ();
181}
182
183EXPORT_SYMBOL(machine_power_off);
184
185/* Called before configuring an on-chip UART.  */
186void as85ep1_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
187{
188	/* Make the shared uart/port pins be uart pins.  */
189	AS85EP1_PORT_PMC(3) |= (0x5 << chan);
190
191	/* The AS85EP1 connects some general-purpose I/O pins on the CPU to
192	   the RTS/CTS lines of UART 1's serial connection.  I/O pins P53
193	   and P54 are RTS and CTS respectively.  */
194	if (chan == 1) {
195		/* Put P53 & P54 in I/O port mode.  */
196		AS85EP1_PORT_PMC(5) &= ~0x18;
197		/* Make P53 an output, and P54 an input.  */
198		AS85EP1_PORT_PM(5) |=  0x10;
199	}
200}
201
202/* Minimum and maximum bounds for the moving upper LED boundary in the
203   clock tick display.  */
204#define MIN_MAX_POS 0
205#define MAX_MAX_POS 7
206
207/* There are MAX_MAX_POS^2 - MIN_MAX_POS^2 cycles in the animation, so if
208   we pick 6 and 0 as above, we get 49 cycles, which is when divided into
209   the standard 100 value for HZ, gives us an almost 1s total time.  */
210#define TICKS_PER_FRAME \
211	(HZ / (MAX_MAX_POS * MAX_MAX_POS - MIN_MAX_POS * MIN_MAX_POS))
212
213static void as85ep1_led_tick ()
214{
215	static unsigned counter = 0;
216	
217	if (++counter == TICKS_PER_FRAME) {
218		static int pos = 0, max_pos = MAX_MAX_POS, dir = 1;
219
220		if (dir > 0 && pos == max_pos) {
221			dir = -1;
222			if (max_pos == MIN_MAX_POS)
223				max_pos = MAX_MAX_POS;
224			else
225				max_pos--;
226		} else {
227			if (dir < 0 && pos == 0)
228				dir = 1;
229
230			if (pos + dir <= max_pos) {
231				/* Each bit of port 0 has a LED. */
232				set_bit (pos, &AS85EP1_PORT_IO(LEDS_PORT));
233				pos += dir;
234				clear_bit (pos, &AS85EP1_PORT_IO(LEDS_PORT));
235			}
236		}
237
238		counter = 0;
239	}
240}