Commit 2e2129f5 authored by Miles Bader's avatar Miles Bader Committed by Linus Torvalds

[PATCH] Add support for AS85EP1 platform to v850 arch

Add support for AS85EP1 platform to v850 arch
parent 4598178e
......@@ -63,6 +63,8 @@ menu "Processor type and features"
bool "NA85E2C-FPGA"
config V850E2_ANNA
bool "Anna"
config V850E_AS85EP1
bool "AS85EP1"
endchoice
......
/* Linker script for the NEC AS85EP1 V850E evaluation board
(CONFIG_V850E_AS85EP1). */
/* Note, all symbols are prefixed with an extra `_' for compatibility with
the existing linux sources. */
_jiffies = _jiffies_64 ;
MEMORY {
/* 1MB of internal memory ($BFbB"L?Na(BRAM). */
iMEM0 : ORIGIN = 0, LENGTH = 0x00100000
/* 1MB of static RAM. */
SRAM : ORIGIN = 0x00400000, LENGTH = 0x00100000
/* About 58MB of DRAM. This can actually be at one of two positions,
determined by jump JP3; we have to use the first position because the
second is partially out of processor instruction addressing range
(though in the second position there's actually 64MB available). */
SDRAM : ORIGIN = 0x00600000, LENGTH = 0x039F8000
}
SECTIONS {
.resetv : {
__intv_start = . ;
*(.intv.reset) /* Reset vector */
} > iMEM0
.text : {
__kram_start = . ;
__stext = . ;
*(.text)
*(.exit.text) /* 2.5 convention */
*(.text.exit) /* 2.4 convention */
*(.text.lock)
*(.exitcall.exit)
__real_etext = . ; /* There may be data after here. */
*(.rodata)
. = ALIGN (0x4) ;
*(.kstrtab)
. = ALIGN (4) ;
*(.call_table_data)
*(.call_table_text)
. = ALIGN (16) ; /* Exception table. */
___start___ex_table = . ;
*(__ex_table)
___stop___ex_table = . ;
___start___ksymtab = . ;/* Kernel symbol table. */
*(__ksymtab)
___stop___ksymtab = . ;
. = ALIGN (4) ;
__etext = . ;
} > SRAM
.data ALIGN (0x4) : {
__sdata = . ;
___data_start = . ;
*(.data)
*(.exit.data) /* 2.5 convention */
*(.data.exit) /* 2.4 convention */
. = ALIGN (16) ;
*(.data.cacheline_aligned)
. = ALIGN (0x2000) ;
*(.data.init_task)
. = ALIGN (0x2000) ;
__edata = . ;
} > SRAM
.bss ALIGN (0x4) : {
__sbss = . ;
*(.bss)
*(COMMON)
. = ALIGN (4) ;
__init_stack_end = . ;
__ebss = . ;
} > SRAM
.init ALIGN (4096) : {
__init_start = . ;
*(.init.text) /* 2.5 convention */
*(.init.data)
*(.text.init) /* 2.4 convention */
*(.data.init)
. = ALIGN (16) ;
___setup_start = . ;
*(.init.setup) /* 2.5 convention */
*(.setup.init) /* 2.4 convention */
___setup_end = . ;
___initcall_start = . ;
*(.initcall.init)
*(.initcall1.init)
*(.initcall2.init)
*(.initcall3.init)
*(.initcall4.init)
*(.initcall5.init)
*(.initcall6.init)
*(.initcall7.init)
. = ALIGN (4) ;
___initcall_end = . ;
. = ALIGN (4) ;
___initramfs_start = . ;
*(.init.ramfs)
___initramfs_end = . ;
/* We stick most of the interrupt vectors here; they'll be
copied into the proper location by the early init code (we
can't put them directly in the right place because of
hardware bugs). The vectors shouldn't need to be
relocated, so we don't have to use `> ... AT> ...' to
split the load/vm addresses (and we can't because of
problems with the loader). */
. = ALIGN (0x10) ;
__intv_copy_src_start = . ;
*(.intv.common) /* Vectors common to all v850e proc. */
*(.intv.mach) /* Machine-specific int. vectors. */
. = ALIGN (0x10) ;
__intv_copy_src_end = . ;
/* This is here so that when we free init memory, the initial
load-area of the interrupt vectors is freed too. */
__init_end = . ;
__kram_end = . ;
__bootmap = . ;
. = . + 4096 ; /* enough for 128MB. */
} > SRAM
/* Where we end up putting the vectors. */
__intv_copy_dst_start = 0x10 ;
__intv_copy_dst_end = __intv_copy_dst_start + (__intv_copy_src_end - __intv_copy_src_start) ;
__intv_end = __intv_copy_dst_end ;
/* Device contents for the root filesystem. */
.root : {
. = ALIGN (4096) ;
__root_fs_image_start = . ;
*(.root)
__root_fs_image_end = . ;
} > SDRAM
}
......@@ -20,6 +20,7 @@ obj-$(CONFIG_MODULES) += module.o v850_ksyms.o
obj-$(CONFIG_V850E_MA1) += ma.o nb85e_utils.o nb85e_timer_d.o
obj-$(CONFIG_V850E_NB85E) += nb85e_intc.o
obj-$(CONFIG_V850E2_ANNA) += anna.o nb85e_intc.o nb85e_utils.o nb85e_timer_d.o
obj-$(CONFIG_V850E_AS85EP1) += as85ep1.o nb85e_intc.o nb85e_utils.o nb85e_timer_d.o
# platform-specific code
obj-$(CONFIG_V850E_SIM) += sim.o simcons.o
obj-$(CONFIG_V850E2_SIM85E2C) += sim85e2c.o nb85e_intc.o memcons.o
......
/*
* arch/v850/kernel/as85ep1.c -- AS85EP1 V850E evaluation chip/board
*
* Copyright (C) 2002 NEC Corporation
* Copyright (C) 2002 Miles Bader <miles@gnu.org>
*
* 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.
*
* Written by Miles Bader <miles@gnu.org>
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/major.h>
#include <linux/irq.h>
#include <asm/machdep.h>
#include <asm/atomic.h>
#include <asm/page.h>
#include <asm/nb85e_timer_d.h>
#include <asm/nb85e_uart.h>
#include "mach.h"
/* SRAM and SDRAM are vaguely contiguous (with a big hole in between; see
mach_reserve_bootmem for details); use both as one big area. */
#define RAM_START SRAM_ADDR
#define RAM_END (SDRAM_ADDR + SDRAM_SIZE)
/* The bits of this port are connected to an 8-LED bar-graph. */
#define LEDS_PORT 4
static void as85ep1_led_tick (void);
extern char _intv_copy_src_start, _intv_copy_src_end;
extern char _intv_copy_dst_start;
void __init mach_early_init (void)
{
const u32 *src;
register u32 *dst asm ("ep");
AS85EP1_CSC(0) = 0x0403;
AS85EP1_BCT(0) = 0xB8B8;
AS85EP1_DWC(0) = 0x0104;
AS85EP1_BCC = 0x0012;
AS85EP1_ASC = 0;
AS85EP1_LBS = 0x00A9;
AS85EP1_RFS(1) = 0x8205;
AS85EP1_RFS(3) = 0x8205;
AS85EP1_SCR(1) = 0x20A9;
AS85EP1_SCR(3) = 0x20A9;
AS85EP1_PORT_PMC(6) = 0xFF; /* A20-25, A0,A1 $BM-8z(B */
AS85EP1_PORT_PMC(7) = 0x0E; /* CS1,2,3 $BM-8z(B */
AS85EP1_PORT_PMC(9) = 0xFF; /* D16-23 $BM-8z(B */
AS85EP1_PORT_PMC(10) = 0xFF; /* D24-31 $BM-8z(B */
AS85EP1_IRAMM = 0x3; /* $BFbB"L?Na(BRAM$B$O!V(Bwrite-mode$B!W$K$J$j$^$9(B */
/* The early chip we have is buggy, so that writing the interrupt
vectors into low RAM may screw up, so for non-ROM kernels, we
only rely on the reset vector being downloaded, and copy the
rest of the interrupt vectors into place here. The specific bug
is that writing address N, where (N & 0x10) == 0x10, will _also_
write to address (N - 0x10). We avoid this (effectively) by
writing in 16-byte chunks backwards from the end. */
src = (u32 *)(((u32)&_intv_copy_src_end - 1) & ~0xF);
dst = (u32 *)&_intv_copy_dst_start
+ (src - (u32 *)&_intv_copy_src_start);
do {
u32 t0 = src[0], t1 = src[1], t2 = src[2], t3 = src[3];
dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
dst -= 4;
src -= 4;
} while (src > (u32 *)&_intv_copy_src_start);
AS85EP1_IRAMM = 0x0; /* $BFbB"L?Na(BRAM$B$O!V(Bread-mode$B!W$K$J$j$^$9(B */
nb85e_intc_disable_irqs ();
}
void __init mach_setup (char **cmdline)
{
#ifdef CONFIG_V850E_NB85E_UART_CONSOLE
nb85e_uart_cons_init (1);
#endif
AS85EP1_PORT_PMC (LEDS_PORT) = 0; /* Make the LEDs port an I/O port. */
AS85EP1_PORT_PM (LEDS_PORT) = 0; /* Make all the bits output pins. */
mach_tick = as85ep1_led_tick;
ROOT_DEV = MKDEV (BLKMEM_MAJOR, 0);
}
void __init mach_get_physical_ram (unsigned long *ram_start,
unsigned long *ram_len)
{
*ram_start = RAM_START;
*ram_len = RAM_END - RAM_START;
}
void __init mach_reserve_bootmem ()
{
extern char _root_fs_image_start, _root_fs_image_end;
u32 root_fs_image_start = (u32)&_root_fs_image_start;
u32 root_fs_image_end = (u32)&_root_fs_image_end;
/* We can't use the space between SRAM and SDRAM, so prevent the
kernel from trying. */
reserve_bootmem (SRAM_ADDR + SRAM_SIZE,
SDRAM_ADDR - (SRAM_ADDR + SRAM_SIZE));
/* Reserve the memory used by the root filesystem image if it's
in RAM. */
if (root_fs_image_end > root_fs_image_start
&& root_fs_image_start >= RAM_START
&& root_fs_image_start < RAM_END)
reserve_bootmem (root_fs_image_start,
root_fs_image_end - root_fs_image_start);
}
void mach_gettimeofday (struct timeval *tv)
{
tv->tv_sec = 0;
tv->tv_usec = 0;
}
void __init mach_sched_init (struct irqaction *timer_action)
{
/* Start hardware timer. */
nb85e_timer_d_configure (0, HZ);
/* Install timer interrupt handler. */
setup_irq (IRQ_INTCMD(0), timer_action);
}
static struct nb85e_intc_irq_init irq_inits[] = {
{ "IRQ", 0, NUM_MACH_IRQS, 1, 7 },
{ "CCC", IRQ_INTCCC(0), IRQ_INTCCC_NUM, 1, 5 },
{ "CMD", IRQ_INTCMD(0), IRQ_INTCMD_NUM, 1, 5 },
{ "SRE", IRQ_INTSRE(0), IRQ_INTSRE_NUM, 3, 3 },
{ "SR", IRQ_INTSR(0), IRQ_INTSR_NUM, 3, 4 },
{ "ST", IRQ_INTST(0), IRQ_INTST_NUM, 3, 5 },
{ 0 }
};
#define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
static struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
void __init mach_init_irqs (void)
{
nb85e_intc_init_irq_types (irq_inits, hw_itypes);
}
void machine_restart (char *__unused)
{
#ifdef CONFIG_RESET_GUARD
disable_reset_guard ();
#endif
asm ("jmp r0"); /* Jump to the reset vector. */
}
void machine_halt (void)
{
#ifdef CONFIG_RESET_GUARD
disable_reset_guard ();
#endif
local_irq_disable (); /* Ignore all interrupts. */
AS85EP1_PORT_IO (LEDS_PORT) = 0xAA; /* Note that we halted. */
for (;;)
asm ("halt; nop; nop; nop; nop; nop");
}
void machine_power_off (void)
{
machine_halt ();
}
/* Called before configuring an on-chip UART. */
void as85ep1_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
{
/* Make the shared uart/port pins be uart pins. */
AS85EP1_PORT_PMC(3) |= (0x5 << chan);
/* The AS85EP1 connects some general-purpose I/O pins on the CPU to
the RTS/CTS lines of UART 1's serial connection. I/O pins P53
and P54 are RTS and CTS respectively. */
if (chan == 1) {
/* Put P53 & P54 in I/O port mode. */
AS85EP1_PORT_PMC(5) &= ~0x18;
/* Make P53 an output, and P54 an input. */
AS85EP1_PORT_PM(5) |= 0x10;
}
}
/* Minimum and maximum bounds for the moving upper LED boundary in the
clock tick display. */
#define MIN_MAX_POS 0
#define MAX_MAX_POS 7
/* There are MAX_MAX_POS^2 - MIN_MAX_POS^2 cycles in the animation, so if
we pick 6 and 0 as above, we get 49 cycles, which is when divided into
the standard 100 value for HZ, gives us an almost 1s total time. */
#define TICKS_PER_FRAME \
(HZ / (MAX_MAX_POS * MAX_MAX_POS - MIN_MAX_POS * MIN_MAX_POS))
static void as85ep1_led_tick ()
{
static unsigned counter = 0;
if (++counter == TICKS_PER_FRAME) {
static int pos = 0, max_pos = MAX_MAX_POS, dir = 1;
if (dir > 0 && pos == max_pos) {
dir = -1;
if (max_pos == MIN_MAX_POS)
max_pos = MAX_MAX_POS;
else
max_pos--;
} else {
if (dir < 0 && pos == 0)
dir = 1;
if (pos + dir <= max_pos) {
/* Each bit of port 0 has a LED. */
set_bit (pos, &AS85EP1_PORT_IO(LEDS_PORT));
pos += dir;
clear_bit (pos, &AS85EP1_PORT_IO(LEDS_PORT));
}
}
counter = 0;
}
}
......@@ -20,6 +20,10 @@
# endif
#endif
#ifdef CONFIG_V850E_AS85EP1
# include "as85ep1.ld"
#endif
#ifdef CONFIG_RTE_CB_MA1
# ifdef CONFIG_ROM_KERNEL
# include "rte_ma1_cb-rom.ld"
......
......@@ -365,7 +365,7 @@ config SERIAL_SUNSAB
config V850E_NB85E_UART
bool "NEC V850E on-chip UART support"
depends on V850E_NB85E || V850E2_ANNA
depends on V850E_NB85E || V850E2_ANNA || V850E_AS85EP1
default y
config V850E_NB85E_UART_CONSOLE
......
/*
* include/asm-v850/as85ep1.h -- AS85EP1 evaluation CPU chip/board
*
* Copyright (C) 2001,2002 NEC Corporation
* Copyright (C) 2001,2002 Miles Bader <miles@gnu.org>
*
* 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.
*
* Written by Miles Bader <miles@gnu.org>
*/
#ifndef __V850_AS85EP1_H__
#define __V850_AS85EP1_H__
#define CPU_ARCH "v850e"
#define CPU_MODEL "as85ep1"
#define CPU_MODEL_LONG "NEC V850E/AS85EP1"
#define PLATFORM "AS85EP1"
#define PLATFORM_LONG "NEC V850E/AS85EP1 evaluation board"
#define CPU_CLOCK_FREQ 96000000 /* 96MHz */
#define SYS_CLOCK_FREQ CPU_CLOCK_FREQ
/* 1MB of static RAM. */
#define SRAM_ADDR 0x00400000
#define SRAM_SIZE 0x00100000 /* 1MB */
/* About 58MB of DRAM. This can actually be at one of two positions,
determined by jump JP3; we have to use the first position because the
second is partially out of processor instruction addressing range
(though in the second position there's actually 64MB available). */
#define SDRAM_ADDR 0x00600000
#define SDRAM_SIZE 0x039F8000 /* approx 58MB */
/* For <asm/page.h> */
#define PAGE_OFFSET SRAM_ADDR
/* We use on-chip RAM, for a few miscellaneous variables that must be
accessible using a load instruction relative to R0. The AS85EP1 chip
16K of internal RAM located slightly before I/O space. */
#define R0_RAM_ADDR 0xFFFF8000
/* AS85EP1 specific control registers. */
#define AS85EP1_CSC_ADDR(n) (0xFFFFF060 + (n) * 2)
#define AS85EP1_CSC(n) (*(volatile u16 *)AS85EP1_CSC_ADDR(n))
#define AS85EP1_BSC_ADDR 0xFFFFF066
#define AS85EP1_BSC (*(volatile u16 *)AS85EP1_BSC_ADDR)
#define AS85EP1_BCT_ADDR(n) (0xFFFFF480 + (n) * 2)
#define AS85EP1_BCT(n) (*(volatile u16 *)AS85EP1_BCT_ADDR(n))
#define AS85EP1_DWC_ADDR(n) (0xFFFFF484 + (n) * 2)
#define AS85EP1_DWC(n) (*(volatile u16 *)AS85EP1_DWC_ADDR(n))
#define AS85EP1_BCC_ADDR 0xFFFFF488
#define AS85EP1_BCC (*(volatile u16 *)AS85EP1_BCC_ADDR)
#define AS85EP1_ASC_ADDR 0xFFFFF48A
#define AS85EP1_ASC (*(volatile u16 *)AS85EP1_ASC_ADDR)
#define AS85EP1_BCP_ADDR 0xFFFFF48C
#define AS85EP1_BCP (*(volatile u16 *)AS85EP1_BCP_ADDR)
#define AS85EP1_LBS_ADDR 0xFFFFF48E
#define AS85EP1_LBS (*(volatile u16 *)AS85EP1_LBS_ADDR)
#define AS85EP1_BMC_ADDR 0xFFFFF498
#define AS85EP1_BMC (*(volatile u16 *)AS85EP1_BMC_ADDR)
#define AS85EP1_PRC_ADDR 0xFFFFF49A
#define AS85EP1_PRC (*(volatile u16 *)AS85EP1_PRC_ADDR)
#define AS85EP1_SCR_ADDR(n) (0xFFFFF4A0 + (n) * 4)
#define AS85EP1_SCR(n) (*(volatile u16 *)AS85EP1_SCR_ADDR(n))
#define AS85EP1_RFS_ADDR(n) (0xFFFFF4A2 + (n) * 4)
#define AS85EP1_RFS(n) (*(volatile u16 *)AS85EP1_RFS_ADDR(n))
#define AS85EP1_IRAMM_ADDR 0xFFFFF80A
#define AS85EP1_IRAMM (*(volatile u8 *)AS85EP1_IRAMM_ADDR)
/* I/O port P0-P13. */
/* Direct I/O. Bits 0-7 are pins Pn0-Pn7. */
#define AS85EP1_PORT_IO_ADDR(n) (0xFFFFF400 + (n) * 2)
#define AS85EP1_PORT_IO(n) (*(volatile u8 *)AS85EP1_PORT_IO_ADDR(n))
/* Port mode (for direct I/O, 0 = output, 1 = input). */
#define AS85EP1_PORT_PM_ADDR(n) (0xFFFFF420 + (n) * 2)
#define AS85EP1_PORT_PM(n) (*(volatile u8 *)AS85EP1_PORT_PM_ADDR(n))
/* Port mode control (0 = direct I/O mode, 1 = alternative I/O mode). */
#define AS85EP1_PORT_PMC_ADDR(n) (0xFFFFF440 + (n) * 2)
#define AS85EP1_PORT_PMC(n) (*(volatile u8 *)AS85EP1_PORT_PMC_ADDR(n))
/* NB85E-style interrupt system. */
#include <asm/nb85e_intc.h>
/* Hardware-specific interrupt numbers (in the kernel IRQ namespace). */
#define IRQ_INTCCC(n) (0x0C + (n))
#define IRQ_INTCCC_NUM 8
#define IRQ_INTCMD(n) (0x14 + (n)) /* interval timer interrupts 0-5 */
#define IRQ_INTCMD_NUM 6
#define IRQ_INTSRE(n) (0x1E + (n)*3) /* UART 0-1 reception error */
#define IRQ_INTSRE_NUM 2
#define IRQ_INTSR(n) (0x1F + (n)*3) /* UART 0-1 reception completion */
#define IRQ_INTSR_NUM 2
#define IRQ_INTST(n) (0x20 + (n)*3) /* UART 0-1 transmission completion */
#define IRQ_INTST_NUM 2
#define NUM_CPU_IRQS 64
#ifndef __ASSEMBLY__
/* Initialize chip interrupts. */
extern void as85ep1_init_irqs (void);
#endif
/* AS85EP1 UART details (basically the same as the V850E/MA1, but 2 channels). */
#define NB85E_UART_NUM_CHANNELS 2
#define NB85E_UART_BASE_FREQ (SYS_CLOCK_FREQ / 4)
#define NB85E_UART_CHIP_NAME "V850E/NA85E"
/* This is a function that gets called before configuring the UART. */
#define NB85E_UART_PRE_CONFIGURE as85ep1_uart_pre_configure
#ifndef __ASSEMBLY__
extern void as85ep1_uart_pre_configure (unsigned chan,
unsigned cflags, unsigned baud);
#endif
/* This board supports RTS/CTS for the on-chip UART, but only for channel 1. */
/* CTS for UART channel 1 is pin P54 (bit 4 of port 5). */
#define NB85E_UART_CTS(chan) ((chan) == 1 ? !(AS85EP1_PORT_IO(5) & 0x10) : 1)
/* RTS for UART channel 1 is pin P53 (bit 3 of port 5). */
#define NB85E_UART_SET_RTS(chan, val) \
do { \
if (chan == 1) { \
unsigned old = AS85EP1_PORT_IO(5); \
if (val) \
AS85EP1_PORT_IO(5) = old & ~0x8; \
else \
AS85EP1_PORT_IO(5) = old | 0x8; \
} \
} while (0)
/* Timer C details. */
#define NB85E_TIMER_C_BASE_ADDR 0xFFFFF600
/* Timer D details (the AS85EP1 actually has 5 of these; should change later). */
#define NB85E_TIMER_D_BASE_ADDR 0xFFFFF540
#define NB85E_TIMER_D_TMD_BASE_ADDR (NB85E_TIMER_D_BASE_ADDR + 0x0)
#define NB85E_TIMER_D_CMD_BASE_ADDR (NB85E_TIMER_D_BASE_ADDR + 0x2)
#define NB85E_TIMER_D_TMCD_BASE_ADDR (NB85E_TIMER_D_BASE_ADDR + 0x4)
#define NB85E_TIMER_D_BASE_FREQ SYS_CLOCK_FREQ
#define NB85E_TIMER_D_TMCD_CS_MIN 2 /* min 2^2 divider */
/* For <asm/param.h> */
#ifndef HZ
#define HZ 100
#endif
#endif /* __V850_AS85EP1_H__ */
......@@ -24,10 +24,13 @@
#include <asm/teg.h>
#endif
/* Anna is both a chip _and_ a platform, so put it in the middle... */
/* These are both chips _and_ platforms, so put them in the middle... */
#ifdef CONFIG_V850E2_ANNA
#include <asm/anna.h>
#endif
#ifdef CONFIG_V850E_AS85EP1
#include <asm/as85ep1.h>
#endif
/* platforms */
#ifdef CONFIG_RTE_CB_MA1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment