[U-Boot-Users] [PATCH 3/7] ARM: Add arm1176 core with s3c6400 SoC

This is a port of s3c6400 sources by Samsung from u-boot-1.1.6.
Signed-off-by: Guennadi Liakhovetski lg@denx.de --- cpu/arm1176/Makefile | 47 + cpu/arm1176/config.mk | 35 + cpu/arm1176/cpu.c | 186 ++++ cpu/arm1176/s3c64xx/Makefile | 46 + cpu/arm1176/s3c64xx/config.mk | 34 + cpu/arm1176/s3c64xx/cpu_init.S | 135 +++ cpu/arm1176/s3c64xx/interrupts.c | 283 ++++++ cpu/arm1176/s3c64xx/nand_cp.c | 132 +++ cpu/arm1176/s3c64xx/speed.c | 133 +++ cpu/arm1176/start.S | 484 ++++++++++ include/asm-arm/arch-s3c64xx/hardware.h | 42 + include/common.h | 2 +- include/s3c6400.h | 1480 +++++++++++++++++++++++++++++++ include/s3c64x0.h | 1184 ++++++++++++++++++++++++ 14 files changed, 4222 insertions(+), 1 deletions(-) create mode 100644 cpu/arm1176/Makefile create mode 100644 cpu/arm1176/config.mk create mode 100644 cpu/arm1176/cpu.c create mode 100644 cpu/arm1176/s3c64xx/Makefile create mode 100644 cpu/arm1176/s3c64xx/config.mk create mode 100644 cpu/arm1176/s3c64xx/cpu_init.S create mode 100644 cpu/arm1176/s3c64xx/interrupts.c create mode 100644 cpu/arm1176/s3c64xx/nand_cp.c create mode 100644 cpu/arm1176/s3c64xx/speed.c create mode 100644 cpu/arm1176/start.S create mode 100644 include/asm-arm/arch-s3c64xx/hardware.h create mode 100644 include/s3c6400.h create mode 100644 include/s3c64x0.h
diff --git a/cpu/arm1176/Makefile b/cpu/arm1176/Makefile new file mode 100644 index 0000000..7701b03 --- /dev/null +++ b/cpu/arm1176/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk new file mode 100644 index 0000000..5083594 --- /dev/null +++ b/cpu/arm1176/config.mk @@ -0,0 +1,35 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, gj@denx.de +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ + -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c new file mode 100644 index 0000000..54228d1 --- /dev/null +++ b/cpu/arm1176/cpu.c @@ -0,0 +1,186 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, gj@denx.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <s3c6400.h> + +/* read co-processor 15, register #1 (control register) */ +static unsigned long read_p15_c1 (void) +{ + unsigned long value; + + __asm__ __volatile__( + "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" + : "=r" (value) + : + : "memory"); + return value; +} + +/* write to co-processor 15, register #1 (control register) */ +static void write_p15_c1 (unsigned long value) +{ + __asm__ __volatile__( + "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" + : + : "r" (value) + : "memory"); + + read_p15_c1(); +} + +static void cp_delay (void) +{ + volatile int i; + + /* Many OMAP regs need at least 2 nops */ + for (i = 0; i < 100; i++); +} + +/* See also ARM Ref. Man. */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_DC (1<<2) /* dcache off/on */ +#define C1_WB (1<<3) /* merging write buffer on/off */ +#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_IC (1<<12) /* icache off/on */ +#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ +#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */ + +int cpu_init (void) +{ + return 0; +} + +int cleanup_before_linux (void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ + + unsigned long i; + + disable_interrupts (); + + /* turn off I/D-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~(C1_DC | C1_IC); + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + + /* flush I/D-cache */ + i = 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */ + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */ + return 0; +} + + +/* * reset the cpu by setting up the watchdog timer and let him time out */ +void reset_cpu (ulong ignored) +{ + printf("reset... \n\n\n"); + SW_RST_REG = 0x6400; + /* loop forever and wait for reset to happen */ + while (1) + { + if (serial_tstc()) + { + serial_getc(); + break; + } + } + /*NOTREACHED*/ +} + +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + disable_interrupts (); + reset_cpu (0); + /*NOTREACHED*/ + return(0); +} + +void icache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); /* get control reg. */ + cp_delay (); + write_p15_c1 (reg | C1_IC); +} + +void icache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IC); +} + +int icache_status (void) +{ + return (read_p15_c1 () & C1_IC) != 0; +} + +/* It makes no sense to use the dcache if the MMU is not enabled */ +void dcache_enable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_DC); +} + +void dcache_disable (void) +{ + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + reg &= ~C1_DC; + write_p15_c1 (reg); +} + +int dcache_status (void) +{ + return (read_p15_c1 () & C1_DC) != 0; +} + diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile new file mode 100644 index 0000000..0a1201d --- /dev/null +++ b/cpu/arm1176/s3c64xx/Makefile @@ -0,0 +1,46 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +OBJS = interrupts.o +#OBJS = nand_cp.o serial.o usb_ohci.o interrupts.o nand.o +COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o + +OBJS += $(COBJS-y) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude .depend + +######################################################################### diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk new file mode 100644 index 0000000..204e880 --- /dev/null +++ b/cpu/arm1176/s3c64xx/config.mk @@ -0,0 +1,34 @@ +# +# (C) Copyright 2002 +# Gary Jennejohn, DENX Software Engineering, gj@denx.de +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \ + -msoft-float + +# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/s3c64xx/cpu_init.S b/cpu/arm1176/s3c64xx/cpu_init.S new file mode 100644 index 0000000..cb7083a --- /dev/null +++ b/cpu/arm1176/s3c64xx/cpu_init.S @@ -0,0 +1,135 @@ +#include <config.h> +#include <s3c6400.h> + + .globl mem_ctrl_asm_init +mem_ctrl_asm_init: + ldr r0, =ELFIN_MEM_SYS_CFG /* Memory subsystem address 0x7e00f120 */ + mov r1, #0xd /* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */ + str r1, [r0] + + ldr r0, =ELFIN_DMC1_BASE /* DMC1 base address 0x7e001000 */ + + ldr r1, =0x4 + str r1, [r0, #INDEX_DMC_MEMC_CMD] + + ldr r1, =DMC_DDR_REFRESH_PRD + str r1, [r0, #INDEX_DMC_REFRESH_PRD] + + ldr r1, =DMC_DDR_CAS_LATENCY + str r1, [r0, #INDEX_DMC_CAS_LATENCY] + + ldr r1, =DMC_DDR_t_DQSS + str r1, [r0, #INDEX_DMC_T_DQSS] + + ldr r1, =DMC_DDR_t_MRD + str r1, [r0, #INDEX_DMC_T_MRD] + + ldr r1, =DMC_DDR_t_RAS + str r1, [r0, #INDEX_DMC_T_RAS] + + ldr r1, =DMC_DDR_t_RC + str r1, [r0, #INDEX_DMC_T_RC] + + ldr r1, =DMC_DDR_t_RCD + ldr r2, =DMC_DDR_schedule_RCD + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RCD] + + ldr r1, =DMC_DDR_t_RFC + ldr r2, =DMC_DDR_schedule_RFC + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RFC] + + ldr r1, =DMC_DDR_t_RP + ldr r2, =DMC_DDR_schedule_RP + orr r1, r1, r2 + str r1, [r0, #INDEX_DMC_T_RP] + + ldr r1, =DMC_DDR_t_RRD + str r1, [r0, #INDEX_DMC_T_RRD] + + ldr r1, =DMC_DDR_t_WR + str r1, [r0, #INDEX_DMC_T_WR] + + ldr r1, =DMC_DDR_t_WTR + str r1, [r0, #INDEX_DMC_T_WTR] + + ldr r1, =DMC_DDR_t_XP + str r1, [r0, #INDEX_DMC_T_XP] + + ldr r1, =DMC_DDR_t_XSR + str r1, [r0, #INDEX_DMC_T_XSR] + + ldr r1, =DMC_DDR_t_ESR + str r1, [r0, #INDEX_DMC_T_ESR] + + ldr r1, =DMC1_MEM_CFG + str r1, [r0, #INDEX_DMC_MEMORY_CFG] + + ldr r1, =DMC1_MEM_CFG2 + str r1, [r0, #INDEX_DMC_MEMORY_CFG2] + + ldr r1, =DMC1_CHIP0_CFG + str r1, [r0, #INDEX_DMC_CHIP_0_CFG] + + ldr r1, =DMC_DDR_32_CFG + str r1, [r0, #INDEX_DMC_USER_CONFIG] + + @DMC0 DDR Chip 0 configuration direct command reg + ldr r1, =DMC_NOP0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + @Precharge All + ldr r1, =DMC_PA0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + @Auto Refresh 2 time + ldr r1, =DMC_AR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + @MRS + ldr r1, =DMC_mDDR_EMR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + @Mode Reg + ldr r1, =DMC_mDDR_MR0 + str r1, [r0, #INDEX_DMC_DIRECT_CMD] + + @Enable DMC1 + mov r1, #0x0 + str r1, [r0, #INDEX_DMC_MEMC_CMD] + +check_dmc1_ready: + ldr r1, [r0, #INDEX_DMC_MEMC_STATUS] + mov r2, #0x3 + and r1, r1, r2 + cmp r1, #0x1 + bne check_dmc1_ready + nop + + mov pc, lr + + +/* Below code is for ARM926EJS and ARM1026EJS */ + .globl cleanDCache +cleanDCache: + mrc p15, 0, pc, c7, c10, 3 /* test/clean D-Cache */ + bne cleanDCache + mov pc, lr + + .globl cleanFlushDCache +cleanFlushDCache: + mrc p15, 0, pc, c7, c14, 3 /* test/cleanflush D-Cache */ + bne cleanFlushDCache + mov pc, lr + + .globl cleanFlushCache +cleanFlushCache: + mrc p15, 0, pc, c7, c14, 3 /* test/cleanflush D-Cache */ + bne cleanFlushCache + mcr p15, 0, r0, c7, c5, 0 /* flush I-Cache */ + mov pc, lr + + .ltorg + diff --git a/cpu/arm1176/s3c64xx/interrupts.c b/cpu/arm1176/s3c64xx/interrupts.c new file mode 100644 index 0000000..d2e857f --- /dev/null +++ b/cpu/arm1176/s3c64xx/interrupts.c @@ -0,0 +1,269 @@ +/* + * (C) Copyright 2003 + * Texas Instruments <www.ti.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke azu@sysgo.de + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, gj@denx.de + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. philippe.robin@arm.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/proc-armv/ptrace.h> +#include <s3c6400.h> + +static ulong timer_load_val; + +#define PRESCALER 167 + +/* macro to read the 16 bit timer */ +static inline ulong READ_TIMER(void) +{ + S3C64XX_TIMERS *const timers = S3C64XX_GetBase_TIMERS(); + + return timers->TCNTO4; +} + +/* Internal tick units */ +/* Last decremneter snapshot */ +static unsigned long lastdec; +/* Monotonic incrementing timer */ +static unsigned long long timestamp; + +void enable_interrupts(void) +{ + return; +} +int disable_interrupts(void) +{ + return 0; +} + +void bad_mode(void) +{ + panic("Resetting CPU ...\n"); + reset_cpu(0); +} + +void show_regs(struct pt_regs *regs) +{ + unsigned long flags; + const char *processor_modes[] = { + "USER_26", "FIQ_26", "IRQ_26", "SVC_26", + "UK4_26", "UK5_26", "UK6_26", "UK7_26", + "UK8_26", "UK9_26", "UK10_26", "UK11_26", + "UK12_26", "UK13_26", "UK14_26", "UK15_26", + "USER_32", "FIQ_32", "IRQ_32", "SVC_32", + "UK4_32", "UK5_32", "UK6_32", "ABT_32", + "UK8_32", "UK9_32", "UK10_32", "UND_32", + "UK12_32", "UK13_32", "UK14_32", "SYS_32", + }; + + flags = condition_codes(regs); + + printf("pc : [<%08lx>] lr : [<%08lx>]\n" + "sp : %08lx ip : %08lx fp : %08lx\n", + instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); + printf("r10: %08lx r9 : %08lx r8 : %08lx\n", regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); + printf("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", + regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); + printf("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", + regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); + printf("Flags: %c%c%c%c", + flags & CC_N_BIT ? 'N' : 'n', + flags & CC_Z_BIT ? 'Z' : 'z', + flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); + printf(" IRQs %s FIQs %s Mode %s%s\n", + interrupts_enabled(regs) ? "on" : "off", + fast_interrupts_enabled(regs) ? "on" : "off", + processor_modes[processor_mode(regs)], thumb_mode(regs) ? " (T)" : ""); +} + +void do_undefined_instruction(struct pt_regs *pt_regs) +{ + printf("undefined instruction\n"); + show_regs(pt_regs); + bad_mode(); +} + +void do_software_interrupt(struct pt_regs *pt_regs) +{ + printf("software interrupt\n"); + show_regs(pt_regs); + bad_mode(); +} + +void do_prefetch_abort(struct pt_regs *pt_regs) +{ + printf("prefetch abort\n"); + show_regs(pt_regs); + bad_mode(); +} + +void do_data_abort(struct pt_regs *pt_regs) +{ + printf("data abort\n"); + show_regs(pt_regs); + bad_mode(); +} + +void do_not_used(struct pt_regs *pt_regs) +{ + printf("not used\n"); + show_regs(pt_regs); + bad_mode(); +} + +void do_fiq(struct pt_regs *pt_regs) +{ + printf("fast interrupt request\n"); + show_regs(pt_regs); + bad_mode(); +} + +void do_irq(struct pt_regs *pt_regs) +{ + printf("interrupt request\n"); + show_regs(pt_regs); + bad_mode(); +} + +int interrupt_init(void) +{ + S3C64XX_TIMERS *const timers = S3C64XX_GetBase_TIMERS(); + + /* use PWM Timer 4 because it has no output */ + /* + * We use the following scheme for the timer: + * Prescaler is hard fixed at 167, divider at 1/4. + * This gives at PCLK frequency 66MHz approx. 10us ticks + * The timer is set to wrap after 100s, at 66MHz this obviously + * happens after 10,000,000 ticks. A long variable can thus + * keep values up to 40,000s, i.e., 11 hours. This should be + * enough for most uses:-) Possible optimizations: select a + * binary-friendly frequency, e.g., 1ms / 128. Also calculate + * the prescaler automatically for other PCLK frequencies. + */ + /* Set timer frequency to 500KHz, at 66MHz we get prescaler=132 < 255 */ + timers->TCFG0 = PRESCALER << 8; + if (timer_load_val == 0) { + /* + * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 and + * prescaler = 16. Should be 10390 @33.25MHz and 15625 @ 50 MHz + */ + timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */ + /*printf("Calculated %lu timer_load_val\n", timer_load_val);*/ + timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000; + } + + /* load value for 10 ms timeout */ + lastdec = timers->TCNTB4 = timer_load_val; + /* auto load, manual update of Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | TCON_4_UPDATE; + /* auto load, start Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON; + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + ulong now = READ_TIMER(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } + else { + /* we have an overflow ... */ + timestamp += lastdec + timer_load_val - now; + } + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + /* We overrun in 100s */ + return (ulong)(timer_load_val / 100); +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer_masked(void) +{ + return get_ticks() / (timer_load_val / (100 * CFG_HZ)); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t * (timer_load_val / (100 * CFG_HZ)); +} + +void udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = (usec + 9) / 10; + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp)/* loop till event */ + /*NOP*/; +} diff --git a/cpu/arm1176/s3c64xx/nand_cp.c b/cpu/arm1176/s3c64xx/nand_cp.c new file mode 100644 index 0000000..f28ebe8 --- /dev/null +++ b/cpu/arm1176/s3c64xx/nand_cp.c @@ -0,0 +1,132 @@ +/* + * $Id: nand_cp.c,v 1.3 2007/02/26 06:19:52 yongkal Exp $ + * + * (C) Copyright 2006 Samsung Electronics + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * You must make sure that all functions in this file are designed + * to load only U-Boot image. + * + * So, DO NOT USE in common read. + * + * By scsuh. + */ + + +#include <common.h> + +#ifdef CONFIG_S3C64XX +#include <asm/io.h> +#include <linux/mtd/nand.h> +#include <asm/arch/s3c6400.h> + +/* + * address format + * 17 16 9 8 0 + * -------------------------------------------- + * | block(12bit) | page(5bit) | offset(9bit) | + * -------------------------------------------- + */ + +static int nandll_read_page (uchar *buf, ulong addr, int large_block) +{ + int i; + int page_size = 512; + + if (large_block) + page_size = 2048; + + NAND_ENABLE_CE(); + + NFCMD_REG = NAND_CMD_READ0; + + /* Write Address */ + NFADDR_REG = 0; + + if (large_block) + NFADDR_REG = 0; + + NFADDR_REG = (addr) & 0xff; + NFADDR_REG = (addr >> 8) & 0xff; + NFADDR_REG = (addr >> 16) & 0xff; + + if (large_block) + NFCMD_REG = NAND_CMD_READSTART; + + NF_TRANSRnB(); + + /* for compatibility(2460). u32 cannot be used. by scsuh */ + for(i=0; i < page_size; i++) { + *buf++ = NFDATA8_REG; + } + + NAND_DISABLE_CE(); + return 0; +} + +/* + * Read data from NAND. + */ +static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block) +{ + uchar *buf = (uchar *)dst_addr; + int i; + uint page_shift = 9; + + if (large_block) + page_shift = 11; + + /* Read pages */ + for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) { + nandll_read_page(buf, i, large_block); + } + + return 0; +} + +int copy_uboot_to_ram (void) +{ + int large_block = 0; + int i; + vu_char id; + + NAND_ENABLE_CE(); + NFCMD_REG = NAND_CMD_READID; + NFADDR_REG = 0x00; + + /* wait for a while */ + for (i=0; i<200; i++); + id = NFDATA8_REG; + id = NFDATA8_REG; + + if (id > 0x80) + large_block = 1; + + /* read NAND Block. + * 128KB ->240KB because of U-Boot size increase. by scsuh + * So, read 0x3c000 bytes not 0x20000(128KB). + */ + return nandll_read_blocks(CFG_PHY_UBOOT_BASE, 0x3c000, large_block); +} + +#endif + diff --git a/cpu/arm1176/s3c64xx/speed.c b/cpu/arm1176/s3c64xx/speed.c new file mode 100644 index 0000000..0b9493a --- /dev/null +++ b/cpu/arm1176/s3c64xx/speed.c @@ -0,0 +1,133 @@ +/* + * (C) Copyright 2001-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This code should work for both the S3C2400 and the S3C2410 + * as they seem to have the same PLL and clock machinery inside. + * The different address mapping is handled by the s3c24xx.h files below. + */ + +#include <common.h> +#include <s3c6400.h> + +#define APLL 0 +#define MPLL 1 +#define EPLL 2 + +/* ------------------------------------------------------------------------- */ +/* NOTE: This describes the proper use of this file. + * + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ + ulong r, m, p, s; + + if (pllreg == APLL) + r = APLL_CON_REG; + else if (pllreg == MPLL) + r = MPLL_CON_REG; + else if (pllreg == EPLL) + r = EPLL_CON0_REG; + else + hang(); + + m = (r >> 16) & 0x3ff; + p = (r >> 8) & 0x3f; + s = r & 0x7; + + return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s))); +} + +/* return ARMCORE frequency */ +ulong get_ARMCLK(void) +{ + ulong div; + + div = CLK_DIV0_REG; + + return get_PLLCLK(APLL) / ((div & 0x7) + 1); +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ + return get_PLLCLK(APLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + ulong fclk; + + uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1; + uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1; + + if (OTHERS_REG & 0x40) + fclk = get_FCLK(); /* SYNC Mode */ + else + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ + + return fclk / (hclk_div * hclkx2_div); +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + ulong fclk; + uint hclkx2_div = ((CLK_DIV0_REG>>9) & 0x7) + 1; + uint pre_div = ((CLK_DIV0_REG>>12) & 0xf) + 1; + + if (OTHERS_REG & 0x40) + fclk = get_FCLK(); /* SYNC Mode */ + else + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */ + + return fclk / (hclkx2_div * pre_div); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + return get_PLLCLK(EPLL); +} + +int print_cpuinfo(void) +{ + printf("\nCPU: S3C6400@%luMHz\n", get_ARMCLK() / 1000000); + printf(" Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ", + get_FCLK()/1000000, get_HCLK()/1000000, get_PCLK() / 1000000); + + if (OTHERS_REG & 0x40) + printf("(SYNC Mode) \n"); + else + printf("(ASYNC Mode) \n"); + return 0; +} diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S new file mode 100644 index 0000000..9749adf --- /dev/null +++ b/cpu/arm1176/start.S @@ -0,0 +1,436 @@ +/* + * armboot - Startup Code for S3C6400/ARM1176 CPU-core + * + * Copyright (c) 2007 Samsung Electronics + * + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) + * 2007-09-21 - Added MoviNAND and OneNAND boot codes by jsgood (jsgood.yang@samsung.com) + * Base codes by scsuh (sc.suh) + */ + +#include <config.h> +#include <version.h> +#ifdef CONFIG_ENABLE_MMU +#include <asm/proc/domain.h> +#endif +#include <s3c6400.h> + +#if !defined(CONFIG_ENABLE_MMU) && !defined(CFG_PHY_UBOOT_BASE) +#define CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE +#endif + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + +.globl _start +_start: b reset +#ifndef CONFIG_NAND_SPL + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: + .word undefined_instruction +_software_interrupt: + .word software_interrupt +_prefetch_abort: + .word prefetch_abort +_data_abort: + .word data_abort +_not_used: + .word not_used +_irq: + .word irq +_fiq: + .word fiq +_pad: + .word 0x12345678 /* now 16*4=64 */ +#else + . = _start + 64 +#endif + +.global _end_vect +_end_vect: + .balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +/* + * Below variable is very important because we use MMU in U-Boot. + * Without it, we cannot run code correctly before MMU is ON. + * by scsuh. + */ +_TEXT_PHY_BASE: + .word CFG_PHY_UBOOT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +/* + * the actual reset code + */ + +reset: + /* + * set the cpu to SVC32 mode + */ + mrs r0,cpsr + bic r0,r0,#0x3f + orr r0,r0,#0xd3 + msr cpsr,r0 + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ + /* + * we do sys-critical inits only at reboot, + * not when booting from ram! + */ +cpu_init_crit: + /* When booting from NAND - it has definitely been a reset, so, no need + * to flush caches and disable the MMU */ +#ifndef CONFIG_NAND_SPL + /* + * flush v4 I/D caches + */ + mov r0, #0 + mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + /* + * disable MMU stuff and caches + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) + bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) + orr r0, r0, #0x00000002 @ set bit 2 (A) Align + orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache + /* Prepare to disable the MMU */ + adr r1, mmu_disable_phys + and r1, r1, #0x3fc /* We presume we're within the first 1024 bytes */ + ldr r2, _TEXT_PHY_BASE + ldr r3, =0xfff00000 + and r2, r2, r3 + orr r2, r2, r1 + b mmu_disable + + .align 5 + /* Run in a single cache-line */ +mmu_disable: + mcr p15, 0, r0, c1, c0, 0 + nop + nop + mov pc, r2 +#endif + +mmu_disable_phys: + /* Peri port setup */ + ldr r0, =0x70000000 + orr r0, r0, #0x13 + mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) + + /* + * Go setup Memory and board specific bits prior to relocation. + */ + bl lowlevel_init /* go setup pll,mux,memory */ + +after_copy: +#ifdef CONFIG_ENABLE_MMU +enable_mmu: + /* enable domain access */ + ldr r5, =0x0000ffff + mcr p15, 0, r5, c3, c0, 0 /* load domain access register */ + + /* Set the TTB register */ + ldr r0, _mmu_table_base + ldr r1, =CFG_PHY_UBOOT_BASE + ldr r2, =0xfff00000 + bic r0, r0, r2 + orr r1, r0, r1 + mcr p15, 0, r1, c2, c0, 0 + + /* Enable the MMU */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #1 /* Set CR_M to enable MMU */ + + /* Prepare to enable the MMU */ + adr r1, skip_hw_init + and r1, r1, #0x3fc + ldr r2, _TEXT_BASE + ldr r3, =0xfff00000 + and r2, r2, r3 + orr r2, r2, r1 + b mmu_enable + + .align 5 + /* Run in a single cache-line */ +mmu_enable: + + mcr p15, 0, r0, c1, c0, 0 + nop + nop + mov pc, r2 +#endif + +skip_hw_init: + /* Set up the stack */ +stack_setup: +#ifdef CONFIG_MEMORY_UPPER_CODE + ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc) +#else + ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ + sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ + sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ + sub sp, r0, #12 /* leave 3 words for abort-stack */ + +#endif + +clear_bss: + ldr r0, _bss_start /* find start of bss segment */ + ldr r1, _bss_end /* stop here */ + mov r2, #0 /* clear */ + +clbss_l: + str r2, [r0] /* clear loop... */ + add r0, r0, #4 + cmp r0, r1 + ble clbss_l + +#ifndef CONFIG_NAND_SPL + ldr pc, _start_armboot + +_start_armboot: + .word start_armboot +#else + b nand_boot +/* .word nand_boot*/ +#endif + +#ifdef CONFIG_ENABLE_MMU +_mmu_table_base: + .word mmu_table +#endif + +#ifndef CONFIG_NAND_SPL +/* + * we assume that cache operation is done before. (eg. cleanup_before_linux()) + * actually, we don't need to do anything about cache if not use d-cache in U-Boot + * So, in this function we clean only MMU. by scsuh + * + * void theLastJump(void *kernel, int arch_num, uint boot_params); + */ +#ifdef CONFIG_ENABLE_MMU + .globl theLastJump +theLastJump: + mov r9, r0 + ldr r3, =0xfff00000 + ldr r4, _TEXT_PHY_BASE + adr r5, phy_last_jump + bic r5, r5, r3 + orr r5, r5, r4 + mov pc, r5 +phy_last_jump: + /* + * disable MMU stuff + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ + bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ + orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ + orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ + mcr p15, 0, r0, c1, c0, 0 + + mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ + + mov r0, #0 + mov pc, r9 +#endif +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + */ + + .macro bad_save_user_regs + sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack + stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 + + ldr r2, _armboot_start + sub r2, r2, #(CFG_MALLOC_LEN) + sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) + add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack + + add r5, sp, #S_SP + mov r1, lr + stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr + mov r0, sp @ save current stack into r0 (param register) + .endm + + .macro get_bad_stack + ldr r13, _armboot_start @ setup our mode stack (enter in banked mode) + sub r13, r13, #(CFG_MALLOC_LEN) @ move past malloc pool + sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack + + str lr, [r13] @ save caller lr in position 0 of saved stack + mrs lr, spsr @ get the spsr + str lr, [r13, #4] @ save spsr in position 1 of saved stack + + mov r13, #MODE_SVC @ prepare SVC-Mode + @ msr spsr_c, r13 + msr spsr, r13 @ switch modes, make sure moves will execute + mov lr, pc @ capture return pc + movs pc, lr @ jump to next instruction & switch modes. + .endm + + .macro get_bad_stack_swi + sub r13, r13, #4 @ space on current stack for scratch reg. + str r0, [r13] @ save R0's value. + ldr r0, _armboot_start @ get data regions start + sub r0, r0, #(CFG_MALLOC_LEN) @ move past malloc pool + sub r0, r0, #(CFG_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack + str lr, [r0] @ save caller lr in position 0 of saved stack + mrs r0, spsr @ get the spsr + str lr, [r0, #4] @ save spsr in position 1 of saved stack + ldr r0, [r13] @ restore r0 + add r13, r13, #4 @ pop stack entry + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + get_bad_stack + bad_save_user_regs + bl do_undefined_instruction + + .align 5 +software_interrupt: + get_bad_stack_swi + bad_save_user_regs + bl do_software_interrupt + + .align 5 +prefetch_abort: + get_bad_stack + bad_save_user_regs + bl do_prefetch_abort + + .align 5 +data_abort: + get_bad_stack + bad_save_user_regs + bl do_data_abort + + .align 5 +not_used: + get_bad_stack + bad_save_user_regs + bl do_not_used + + .align 5 +irq: + get_bad_stack + bad_save_user_regs + bl do_irq + + .align 5 +fiq: + get_bad_stack + bad_save_user_regs + bl do_fiq +#endif /* CONFIG_NAND_SPL */ diff --git a/include/asm-arm/arch-s3c64xx/hardware.h b/include/asm-arm/arch-s3c64xx/hardware.h new file mode 100644 index 0000000..c3deb08 --- /dev/null +++ b/include/asm-arm/arch-s3c64xx/hardware.h @@ -0,0 +1,42 @@ +#ifndef _ARCH_HARDWARE_H_ +#define _ARCH_HARDWARE_H_ + +#include <asm/sizes.h> + +#ifndef __ASSEMBLY__ +#define UData(Data) ((unsigned long) (Data)) + +#define __REG(x) (*(vu_long *)(x)) +#define __REGl(x) (*(vu_long *)(x)) +#define __REGw(x) (*(vu_short *)(x)) +#define __REGb(x) (*(vu_char *)(x)) +#define __REG2(x,y) (*(vu_long *)((x) + (y))) +#else +#define UData(Data) (Data) + +#define __REG(x) (x) +#define __REGl(x) (x) +#define __REGw(x) (x) +#define __REGb(x) (x) +#define __REG2(x,y) ((x) + (y)) +#endif + +#define Fld(Size, Shft) (((Size) << 16) + (Shft)) + +#define FSize(Field) ((Field) >> 16) +#define FShft(Field) ((Field) & 0x0000FFFF) +#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field)) +#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1) +#define F1stBit(Field) (UData (1) << FShft (Field)) + +#define FClrBit(Data, Bit) (Data = (Data & ~(Bit))) +#define FClrFld(Data, Field) (Data = (Data & ~FMsk(Field))) + +#define FInsrt(Value, Field) \ + (UData (Value) << FShft (Field)) + +#define FExtr(Data, Field) \ + ((UData (Data) >> FShft (Field)) & FAlnMsk (Field)) + +#endif /* _ARCH_HARDWARE_H_ */ + diff --git a/include/common.h b/include/common.h index 2fcb1fd..50b94c3 100644 --- a/include/common.h +++ b/include/common.h @@ -489,7 +489,7 @@ int prt_mpc8220_clks (void); ulong get_OPB_freq (void); ulong get_PCI_freq (void); #endif -#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X) +#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400) void s3c2410_irq(void); #define ARM920_IRQ_CALLBACK s3c2410_irq ulong get_FCLK (void); diff --git a/include/s3c6400.h b/include/s3c6400.h new file mode 100644 index 0000000..ab215a2 --- /dev/null +++ b/include/s3c6400.h @@ -0,0 +1,880 @@ +/* + * (C) Copyright 2007 + * Byungjae Lee, Samsung Erectronics, bjlee@samsung.com. + * - only support for S3C6400 + * $Id: s3c6400.h,v 1.17 2007/10/17 09:54:48 jsgood Exp $ + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/************************************************ + * NAME : s3c6400.h + * + * Based on S3C6400 User's manual Rev 0.0 + ************************************************/ + +#ifndef __S3C6400_H__ +#define __S3C6400_H__ + +#ifndef CONFIG_S3C6400 +#define CONFIG_S3C6400 1 +#endif + +#define S3C64XX_UART_CHANNELS 3 +#define S3C64XX_SPI_CHANNELS 2 + +#include <asm/hardware.h> + +#ifndef __ASSEMBLY__ +typedef enum { + S3C64XX_UART0, + S3C64XX_UART1, + S3C64XX_UART2, +} S3C64XX_UARTS_NR; + +#include "s3c64x0.h" +#endif + +#define ELFIN_CLOCK_POWER_BASE 0x7e00f000 + +/* Clock & Power Controller for mDirac3*/ +#define APLL_LOCK_OFFSET 0x00 +#define MPLL_LOCK_OFFSET 0x04 +#define EPLL_LOCK_OFFSET 0x08 +#define APLL_CON_OFFSET 0x0C +#define MPLL_CON_OFFSET 0x10 +#define EPLL_CON0_OFFSET 0x14 +#define EPLL_CON1_OFFSET 0x18 +#define CLK_SRC_OFFSET 0x1C +#define CLK_DIV0_OFFSET 0x20 +#define CLK_DIV1_OFFSET 0x24 +#define CLK_DIV2_OFFSET 0x28 +#define CLK_OUT_OFFSET 0x2C +#define HCLK_GATE_OFFSET 0x30 +#define PCLK_GATE_OFFSET 0x34 +#define SCLK_GATE_OFFSET 0x38 +#define AHB_CON0_OFFSET 0x100 +#define AHB_CON1_OFFSET 0x104 +#define AHB_CON2_OFFSET 0x108 +#define SELECT_DMA_OFFSET 0x110 +#define SW_RST_OFFSET 0x114 +#define SYS_ID_OFFSET 0x118 +#define MEM_SYS_CFG_OFFSET 0x120 +#define QOS_OVERRIDE0_OFFSET 0x124 +#define QOS_OVERRIDE1_OFFSET 0x128 +#define MEM_CFG_STAT_OFFSET 0x12C +#define PWR_CFG_OFFSET 0x804 +#define EINT_MASK_OFFSET 0x808 +#define NOR_CFG_OFFSET 0x810 +#define STOP_CFG_OFFSET 0x814 +#define SLEEP_CFG_OFFSET 0x818 +#define OSC_FREQ_OFFSET 0x820 +#define OSC_STABLE_OFFSET 0x824 +#define PWR_STABLE_OFFSET 0x828 +#define FPC_STABLE_OFFSET 0x82C +#define MTC_STABLE_OFFSET 0x830 +#define OTHERS_OFFSET 0x900 +#define RST_STAT_OFFSET 0x904 +#define WAKEUP_STAT_OFFSET 0x908 +#define BLK_PWR_STAT_OFFSET 0x90C +#define INF_REG0_OFFSET 0xA00 +#define INF_REG1_OFFSET 0xA04 +#define INF_REG2_OFFSET 0xA08 +#define INF_REG3_OFFSET 0xA0C +#define INF_REG4_OFFSET 0xA10 +#define INF_REG5_OFFSET 0xA14 +#define INF_REG6_OFFSET 0xA18 +#define INF_REG7_OFFSET 0xA1C + +#define OSC_CNT_VAL_OFFSET 0x824 +#define PWR_CNT_VAL_OFFSET 0x828 +#define FPC_CNT_VAL_OFFSET 0x82C +#define MTC_CNT_VAL_OFFSET 0x830 + +#define APLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET) +#define MPLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET) +#define EPLL_LOCK_REG __REG(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET) +#define APLL_CON_REG __REG(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET) +#define MPLL_CON_REG __REG(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET) +#define EPLL_CON0_REG __REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET) +#define EPLL_CON1_REG __REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET) +#define CLK_SRC_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET) +#define CLK_DIV0_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET) +#define CLK_DIV1_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET) +#define CLK_DIV2_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET) +#define CLK_OUT_REG __REG(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET) +#define HCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET) +#define PCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET) +#define SCLK_GATE_REG __REG(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET) +#define AHB_CON0_REG __REG(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET) +#define AHB_CON1_REG __REG(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET) +#define AHB_CON2_REG __REG(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET) +#define SELECT_DMA_REG __REG(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET) +#define SW_RST_REG __REG(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET) +#define SYS_ID_REG __REG(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET) +#define MEM_SYS_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET) +#define QOS_OVERRIDE0_REG __REG(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET) +#define QOS_OVERRIDE1_REG __REG(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET) +#define MEM_CFG_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET) +#define PWR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET) +#define EINT_MASK_REG __REG(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET) +#define NOR_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET) +#define STOP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET) +#define SLEEP_CFG_REG __REG(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET) +#define OSC_FREQ_REG __REG(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET) +#define OSC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET) +#define PWR_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET) +#define FPC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET) +#define MTC_CNT_VAL_REG __REG(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET) +#define OTHERS_REG __REG(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET) +#define RST_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET) +#define WAKEUP_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET) +#define BLK_PWR_STAT_REG __REG(ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET) +#define INF_REG0_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET) +#define INF_REG1_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET) +#define INF_REG2_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET) +#define INF_REG3_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET) +#define INF_REG4_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET) +#define INF_REG5_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET) +#define INF_REG6_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET) +#define INF_REG7_REG __REG(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET) + +#define APLL_LOCK (ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET) +#define MPLL_LOCK (ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET) +#define EPLL_LOCK (ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET) +#define APLL_CON (ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET) +#define MPLL_CON (ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET) +#define EPLL_CON0 (ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET) +#define EPLL_CON1 (ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET) +#define CLK_SRC (ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET) +#define CLK_DIV0 (ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET) +#define CLK_DIV1 (ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET) +#define CLK_DIV2 (ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET) +#define CLK_OUT (ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET) +#define HCLK_GATE (ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET) +#define PCLK_GATE (ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET) +#define SCLK_GATE (ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET) +#define AHB_CON0 (ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET) +#define AHB_CON1 (ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET) +#define AHB_CON2 (ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET) +#define SELECT_DMA (ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET) +#define SW_RST (ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET) +#define SYS_ID (ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET) +#define MEM_SYS_CFG (ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET) +#define QOS_OVERRIDE0 (ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET) +#define QOS_OVERRIDE1 (ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET) +#define MEM_CFG_STAT (ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET) +#define PWR_CFG (ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET) +#define EINT_MASK (ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET) +#define NOR_CFG (ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET) +#define STOP_CFG (ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET) +#define SLEEP_CFG (ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET) +#define OSC_FREQ (ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET) +#define OSC_CNT_VAL (ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET) +#define PWR_CNT_VAL (ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET) +#define FPC_CNT_VAL (ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET) +#define MTC_CNT_VAL (ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET) +#define OTHERS (ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET) +#define RST_STAT (ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET) +#define WAKEUP_STAT (ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET) +#define BLK_PWR_STAT (ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET) +#define INF_REG0 (ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET) +#define INF_REG1 (ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET) +#define INF_REG2 (ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET) +#define INF_REG3 (ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET) +#define INF_REG4 (ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET) +#define INF_REG5 (ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET) +#define INF_REG6 (ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET) +#define INF_REG7 (ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET) + + +/* + * GPIO + */ +#define ELFIN_GPIO_BASE 0x7f008000 + +#define GPACON_OFFSET 0x00 +#define GPADAT_OFFSET 0x04 +#define GPAPUD_OFFSET 0x08 +#define GPACONSLP_OFFSET 0x0C +#define GPAPUDSLP_OFFSET 0x10 +#define GPBCON_OFFSET 0x20 +#define GPBDAT_OFFSET 0x04 +#define GPBPUD_OFFSET 0x08 +#define GPBCONSLP_OFFSET 0x0C +#define GPBPUDSLP_OFFSET 0x30 +#define GPCCON_OFFSET 0x40 +#define GPCDAT_OFFSET 0x44 +#define GPCPUD_OFFSET 0x48 +#define GPCCONSLP_OFFSET 0x4C +#define GPCPUDSLP_OFFSET 0x50 +#define GPDCON_OFFSET 0x60 +#define GPDDAT_OFFSET 0x64 +#define GPDPUD_OFFSET 0x68 +#define GPDCONSLP_OFFSET 0x6C +#define GPDPUDSLP_OFFSET 0x70 +#define GPECON_OFFSET 0x80 +#define GPEDAT_OFFSET 0x84 +#define GPEPUD_OFFSET 0x88 +#define GPECONSLP_OFFSET 0x8C +#define GPEPUDSLP_OFFSET 0x90 +#define GPFCON_OFFSET 0xA0 +#define GPFDAT_OFFSET 0xA4 +#define GPFPUD_OFFSET 0xA8 +#define GPFCONSLP_OFFSET 0xAC +#define GPFPUDSLP_OFFSET 0xB0 +#define GPGCON_OFFSET 0xC0 +#define GPGDAT_OFFSET 0xC4 +#define GPGPUD_OFFSET 0xC8 +#define GPGCONSLP_OFFSET 0xCC +#define GPGPUDSLP_OFFSET 0xD0 +#define GPHCON0_OFFSET 0xE0 +#define GPHCON1_OFFSET 0xE4 +#define GPHDAT_OFFSET 0xE8 +#define GPHPUD_OFFSET 0xEC +#define GPHCONSLP_OFFSET 0xF0 +#define GPHPUDSLP_OFFSET 0xF4 +#define GPICON_OFFSET 0x100 +#define GPIDAT_OFFSET 0x104 +#define GPIPUD_OFFSET 0x108 +#define GPICONSLP_OFFSET 0x10C +#define GPIPUDSLP_OFFSET 0x110 +#define GPJCON_OFFSET 0x120 +#define GPJDAT_OFFSET 0x124 +#define GPJPUD_OFFSET 0x128 +#define GPJCONSLP_OFFSET 0x12C +#define GPJPUDSLP_OFFSET 0x130 +#define MEM0DRVCON_OFFSET 0x1D0 +#define MEM1DRVCON_OFFSET 0x1D4 +#define GPKCON0_OFFSET 0x800 +#define GPKCON1_OFFSET 0x804 +#define GPKDAT_OFFSET 0x808 +#define GPKPUD_OFFSET 0x80C +#define GPLCON0_OFFSET 0x810 +#define GPLCON1_OFFSET 0x814 +#define GPLDAT_OFFSET 0x818 +#define GPLPUD_OFFSET 0x81C +#define GPMCON_OFFSET 0x820 +#define GPMDAT_OFFSET 0x824 +#define GPMPUD_OFFSET 0x828 +#define GPNCON_OFFSET 0x830 +#define GPNDAT_OFFSET 0x834 +#define GPNPUD_OFFSET 0x838 +#define GPOCON_OFFSET 0x140 +#define GPODAT_OFFSET 0x144 +#define GPOPUD_OFFSET 0x148 +#define GPOCONSLP_OFFSET 0x14C +#define GPOPUDSLP_OFFSET 0x150 +#define GPPCON_OFFSET 0x160 +#define GPPDAT_OFFSET 0x164 +#define GPPPUD_OFFSET 0x168 +#define GPPCONSLP_OFFSET 0x16C +#define GPPPUDSLP_OFFSET 0x170 +#define GPQCON_OFFSET 0x180 +#define GPQDAT_OFFSET 0x184 +#define GPQPUD_OFFSET 0x188 +#define GPQCONSLP_OFFSET 0x18C +#define GPQPUDSLP_OFFSET 0x190 + +#define EINTPEND_OFFSET 0x924 + +#define GPACON_REG __REG(ELFIN_GPIO_BASE+GPACON_OFFSET) +#define GPADAT_REG __REG(ELFIN_GPIO_BASE+GPADAT_OFFSET) +#define GPAPUD_REG __REG(ELFIN_GPIO_BASE+GPAPUD_OFFSET) +#define GPACONSLP_REG __REG(ELFIN_GPIO_BASE+GPACONSLP_OFFSET) +#define GPAPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET) +#define GPBCON_REG __REG(ELFIN_GPIO_BASE+GPBCON_OFFSET) +#define GPBDAT_REG __REG(ELFIN_GPIO_BASE+GPBDAT_OFFSET) +#define GPBPUD_REG __REG(ELFIN_GPIO_BASE+GPBPUD_OFFSET) +#define GPBCONSLP_REG __REG(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET) +#define GPBPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET) +#define GPCCON_REG __REG(ELFIN_GPIO_BASE+GPCCON_OFFSET) +#define GPCDAT_REG __REG(ELFIN_GPIO_BASE+GPCDAT_OFFSET) +#define GPCPUD_REG __REG(ELFIN_GPIO_BASE+GPCPUD_OFFSET) +#define GPCCONSLP_REG __REG(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET) +#define GPCPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET) +#define GPDCON_REG __REG(ELFIN_GPIO_BASE+GPDCON_OFFSET) +#define GPDDAT_REG __REG(ELFIN_GPIO_BASE+GPDDAT_OFFSET) +#define GPDPUD_REG __REG(ELFIN_GPIO_BASE+GPDPUD_OFFSET) +#define GPDCONSLP_REG __REG(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET) +#define GPDPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET) +#define GPECON_REG __REG(ELFIN_GPIO_BASE+GPECON_OFFSET) +#define GPEDAT_REG __REG(ELFIN_GPIO_BASE+GPEDAT_OFFSET) +#define GPEPUD_REG __REG(ELFIN_GPIO_BASE+GPEPUD_OFFSET) +#define GPECONSLP_REG __REG(ELFIN_GPIO_BASE+GPECONSLP_OFFSET) +#define GPEPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET) +#define GPFCON_REG __REG(ELFIN_GPIO_BASE+GPFCON_OFFSET) +#define GPFDAT_REG __REG(ELFIN_GPIO_BASE+GPFDAT_OFFSET) +#define GPFPUD_REG __REG(ELFIN_GPIO_BASE+GPFPUD_OFFSET) +#define GPFCONSLP_REG __REG(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET) +#define GPFPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET) +#define GPGCON_REG __REG(ELFIN_GPIO_BASE+GPGCON_OFFSET) +#define GPGDAT_REG __REG(ELFIN_GPIO_BASE+GPGDAT_OFFSET) +#define GPGPUD_REG __REG(ELFIN_GPIO_BASE+GPGPUD_OFFSET) +#define GPGCONSLP_REG __REG(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET) +#define GPGPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET) +#define GPHCON0_REG __REG(ELFIN_GPIO_BASE+GPHCON0_OFFSET) +#define GPHCON1_REG __REG(ELFIN_GPIO_BASE+GPHCON1_OFFSET) +#define GPHDAT_REG __REG(ELFIN_GPIO_BASE+GPHDAT_OFFSET) +#define GPHPUD_REG __REG(ELFIN_GPIO_BASE+GPHPUD_OFFSET) +#define GPHCONSLP_REG __REG(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET) +#define GPHPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET) +#define GPICON_REG __REG(ELFIN_GPIO_BASE+GPICON_OFFSET) +#define GPIDAT_REG __REG(ELFIN_GPIO_BASE+GPIDAT_OFFSET) +#define GPIPUD_REG __REG(ELFIN_GPIO_BASE+GPIPUD_OFFSET) +#define GPICONSLP_REG __REG(ELFIN_GPIO_BASE+GPICONSLP_OFFSET) +#define GPIPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET) +#define GPJCON_REG __REG(ELFIN_GPIO_BASE+GPJCON_OFFSET) +#define GPJDAT_REG __REG(ELFIN_GPIO_BASE+GPJDAT_OFFSET) +#define GPJPUD_REG __REG(ELFIN_GPIO_BASE+GPJPUD_OFFSET) +#define GPJCONSLP_REG __REG(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET) +#define GPJPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET) +#define GPKCON0_REG __REG(ELFIN_GPIO_BASE+GPKCON0_OFFSET) +#define GPKCON1_REG __REG(ELFIN_GPIO_BASE+GPKCON1_OFFSET) +#define GPKDAT_REG __REG(ELFIN_GPIO_BASE+GPKDAT_OFFSET) +#define GPKPUD_REG __REG(ELFIN_GPIO_BASE+GPKPUD_OFFSET) +#define GPLCON0_REG __REG(ELFIN_GPIO_BASE+GPLCON0_OFFSET) +#define GPLCON1_REG __REG(ELFIN_GPIO_BASE+GPLCON1_OFFSET) +#define GPLDAT_REG __REG(ELFIN_GPIO_BASE+GPLDAT_OFFSET) +#define GPLPUD_REG __REG(ELFIN_GPIO_BASE+GPLPUD_OFFSET) +#define GPMCON_REG __REG(ELFIN_GPIO_BASE+GPMCON_OFFSET) +#define GPMDAT_REG __REG(ELFIN_GPIO_BASE+GPMDAT_OFFSET) +#define GPMPUD_REG __REG(ELFIN_GPIO_BASE+GPMPUD_OFFSET) +#define GPNCON_REG __REG(ELFIN_GPIO_BASE+GPNCON_OFFSET) +#define GPNDAT_REG __REG(ELFIN_GPIO_BASE+GPNDAT_OFFSET) +#define GPNPUD_REG __REG(ELFIN_GPIO_BASE+GPNPUD_OFFSET) +#define GPOCON_REG __REG(ELFIN_GPIO_BASE+GPOCON_OFFSET) +#define GPODAT_REG __REG(ELFIN_GPIO_BASE+GPODAT_OFFSET) +#define GPOPUD_REG __REG(ELFIN_GPIO_BASE+GPOPUD_OFFSET) +#define GPOCONSLP_REG __REG(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET) +#define GPOPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET) +#define GPPCON_REG __REG(ELFIN_GPIO_BASE+GPPCON_OFFSET) +#define GPPDAT_REG __REG(ELFIN_GPIO_BASE+GPPDAT_OFFSET) +#define GPPPUD_REG __REG(ELFIN_GPIO_BASE+GPPPUD_OFFSET) +#define GPPCONSLP_REG __REG(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET) +#define GPPPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET) +#define GPQCON_REG __REG(ELFIN_GPIO_BASE+GPQCON_OFFSET) +#define GPQDAT_REG __REG(ELFIN_GPIO_BASE+GPQDAT_OFFSET) +#define GPQPUD_REG __REG(ELFIN_GPIO_BASE+GPQPUD_OFFSET) +#define GPQCONSLP_REG __REG(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET) +#define GPQPUDSLP_REG __REG(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET) + +/* + * Bus Matrix + */ +#define ELFIN_MEM_SYS_CFG 0x7e00f120 + +#define GPACON (ELFIN_GPIO_BASE+GPACON_OFFSET) +#define GPADAT (ELFIN_GPIO_BASE+GPADAT_OFFSET) +#define GPAPUD (ELFIN_GPIO_BASE+GPAPUD_OFFSET) +#define GPACONSLP (ELFIN_GPIO_BASE+GPACONSLP_OFFSET) +#define GPAPUDSLP (ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET) +#define GPBCON (ELFIN_GPIO_BASE+GPBCON_OFFSET) +#define GPBDAT (ELFIN_GPIO_BASE+GPBDAT_OFFSET) +#define GPBPUD (ELFIN_GPIO_BASE+GPBPUD_OFFSET) +#define GPBCONSLP (ELFIN_GPIO_BASE+GPBCONSLP_OFFSET) +#define GPBPUDSLP (ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET) +#define GPCCON (ELFIN_GPIO_BASE+GPCCON_OFFSET) +#define GPCDAT (ELFIN_GPIO_BASE+GPCDAT_OFFSET) +#define GPCPUD (ELFIN_GPIO_BASE+GPCPUD_OFFSET) +#define GPCCONSLP (ELFIN_GPIO_BASE+GPCCONSLP_OFFSET) +#define GPCPUDSLP (ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET) +#define GPDCON (ELFIN_GPIO_BASE+GPDCON_OFFSET) +#define GPDDAT (ELFIN_GPIO_BASE+GPDDAT_OFFSET) +#define GPDPUD (ELFIN_GPIO_BASE+GPDPUD_OFFSET) +#define GPDCONSLP (ELFIN_GPIO_BASE+GPDCONSLP_OFFSET) +#define GPDPUDSLP (ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET) +#define GPECON (ELFIN_GPIO_BASE+GPECON_OFFSET) +#define GPEDAT (ELFIN_GPIO_BASE+GPEDAT_OFFSET) +#define GPEPUD (ELFIN_GPIO_BASE+GPEPUD_OFFSET) +#define GPECONSLP (ELFIN_GPIO_BASE+GPECONSLP_OFFSET) +#define GPEPUDSLP (ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET) +#define GPFCON (ELFIN_GPIO_BASE+GPFCON_OFFSET) +#define GPFDAT (ELFIN_GPIO_BASE+GPFDAT_OFFSET) +#define GPFPUD (ELFIN_GPIO_BASE+GPFPUD_OFFSET) +#define GPFCONSLP (ELFIN_GPIO_BASE+GPFCONSLP_OFFSET) +#define GPFPUDSLP (ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET) +#define GPGCON (ELFIN_GPIO_BASE+GPGCON_OFFSET) +#define GPGDAT (ELFIN_GPIO_BASE+GPGDAT_OFFSET) +#define GPGPUD (ELFIN_GPIO_BASE+GPGPUD_OFFSET) +#define GPGCONSLP (ELFIN_GPIO_BASE+GPGCONSLP_OFFSET) +#define GPGPUDSLP (ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET) +#define GPHCON0 (ELFIN_GPIO_BASE+GPHCON0_OFFSET) +#define GPHCON1 (ELFIN_GPIO_BASE+GPHCON1_OFFSET) +#define GPHDAT (ELFIN_GPIO_BASE+GPHDAT_OFFSET) +#define GPHPUD (ELFIN_GPIO_BASE+GPHPUD_OFFSET) +#define GPHCONSLP (ELFIN_GPIO_BASE+GPHCONSLP_OFFSET) +#define GPHPUDSLP (ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET) +#define GPICON (ELFIN_GPIO_BASE+GPICON_OFFSET) +#define GPIDAT (ELFIN_GPIO_BASE+GPIDAT_OFFSET) +#define GPIPUD (ELFIN_GPIO_BASE+GPIPUD_OFFSET) +#define GPICONSLP (ELFIN_GPIO_BASE+GPICONSLP_OFFSET) +#define GPIPUDSLP (ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET) +#define GPJCON (ELFIN_GPIO_BASE+GPJCON_OFFSET) +#define GPJDAT (ELFIN_GPIO_BASE+GPJDAT_OFFSET) +#define GPJPUD (ELFIN_GPIO_BASE+GPJPUD_OFFSET) +#define GPJCONSLP (ELFIN_GPIO_BASE+GPJCONSLP_OFFSET) +#define GPJPUDSLP (ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET) +#define GPKCON0 (ELFIN_GPIO_BASE+GPKCON0_OFFSET) +#define GPKCON1 (ELFIN_GPIO_BASE+GPKCON1_OFFSET) +#define GPKDAT (ELFIN_GPIO_BASE+GPKDAT_OFFSET) +#define GPKPUD (ELFIN_GPIO_BASE+GPKPUD_OFFSET) +#define GPLCON0 (ELFIN_GPIO_BASE+GPLCON0_OFFSET) +#define GPLCON1 (ELFIN_GPIO_BASE+GPLCON1_OFFSET) +#define GPLDAT (ELFIN_GPIO_BASE+GPLDAT_OFFSET) +#define GPLPUD (ELFIN_GPIO_BASE+GPLPUD_OFFSET) +#define GPMCON (ELFIN_GPIO_BASE+GPMCON_OFFSET) +#define GPMDAT (ELFIN_GPIO_BASE+GPMDAT_OFFSET) +#define GPMPUD (ELFIN_GPIO_BASE+GPMPUD_OFFSET) +#define GPNCON (ELFIN_GPIO_BASE+GPNCON_OFFSET) +#define GPNDAT (ELFIN_GPIO_BASE+GPNDAT_OFFSET) +#define GPNPUD (ELFIN_GPIO_BASE+GPNPUD_OFFSET) +#define GPOCON (ELFIN_GPIO_BASE+GPOCON_OFFSET) +#define GPODAT (ELFIN_GPIO_BASE+GPODAT_OFFSET) +#define GPOPUD (ELFIN_GPIO_BASE+GPOPUD_OFFSET) +#define GPOCONSLP (ELFIN_GPIO_BASE+GPOCONSLP_OFFSET) +#define GPOPUDSLP (ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET) +#define GPPCON (ELFIN_GPIO_BASE+GPPCON_OFFSET) +#define GPPDAT (ELFIN_GPIO_BASE+GPPDAT_OFFSET) +#define GPPPUD (ELFIN_GPIO_BASE+GPPPUD_OFFSET) +#define GPPCONSLP (ELFIN_GPIO_BASE+GPPCONSLP_OFFSET) +#define GPPPUDSLP (ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET) +#define GPQCON (ELFIN_GPIO_BASE+GPQCON_OFFSET) +#define GPQDAT (ELFIN_GPIO_BASE+GPQDAT_OFFSET) +#define GPQPUD (ELFIN_GPIO_BASE+GPQPUD_OFFSET) +#define GPQCONSLP (ELFIN_GPIO_BASE+GPQCONSLP_OFFSET) +#define GPQPUDSLP (ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET) + +/* + * Memory controller + */ +#define ELFIN_SROM_BASE 0x70000000 + +#define SROM_BW_REG __REG(ELFIN_SROM_BASE+0x0) +#define SROM_BC0_REG __REG(ELFIN_SROM_BASE+0x4) +#define SROM_BC1_REG __REG(ELFIN_SROM_BASE+0x8) +#define SROM_BC2_REG __REG(ELFIN_SROM_BASE+0xC) +#define SROM_BC3_REG __REG(ELFIN_SROM_BASE+0x10) +#define SROM_BC4_REG __REG(ELFIN_SROM_BASE+0x14) +#define SROM_BC5_REG __REG(ELFIN_SROM_BASE+0x18) + +/* + * SDRAM Controller + */ +#define ELFIN_DMC0_BASE 0x7e000000 +#define ELFIN_DMC1_BASE 0x7e001000 + +#define INDEX_DMC_MEMC_STATUS (0x00) +#define INDEX_DMC_MEMC_CMD (0x04) +#define INDEX_DMC_DIRECT_CMD (0x08) +#define INDEX_DMC_MEMORY_CFG (0x0C) +#define INDEX_DMC_REFRESH_PRD (0x10) +#define INDEX_DMC_CAS_LATENCY (0x14) +#define INDEX_DMC_T_DQSS (0x18) +#define INDEX_DMC_T_MRD (0x1C) +#define INDEX_DMC_T_RAS (0x20) +#define INDEX_DMC_T_RC (0x24) +#define INDEX_DMC_T_RCD (0x28) +#define INDEX_DMC_T_RFC (0x2C) +#define INDEX_DMC_T_RP (0x30) +#define INDEX_DMC_T_RRD (0x34) +#define INDEX_DMC_T_WR (0x38) +#define INDEX_DMC_T_WTR (0x3C) +#define INDEX_DMC_T_XP (0x40) +#define INDEX_DMC_T_XSR (0x44) +#define INDEX_DMC_T_ESR (0x48) +#define INDEX_DMC_MEMORY_CFG2 (0x4C) +#define INDEX_DMC_CHIP_0_CFG (0x200) +#define INDEX_DMC_CHIP_1_CFG (0x204) +#define INDEX_DMC_CHIP_2_CFG (0x208) +#define INDEX_DMC_CHIP_3_CFG (0x20C) +#define INDEX_DMC_USER_STATUS (0x300) +#define INDEX_DMC_USER_CONFIG (0x304) + +/* + * Memory Chip direct command + */ +#define DMC_NOP0 0x0c0000 +#define DMC_NOP1 0x1c0000 +#define DMC_PA0 0x000000 /* Precharge all */ +#define DMC_PA1 0x100000 +#define DMC_AR0 0x040000 /* Autorefresh */ +#define DMC_AR1 0x140000 +#define DMC_SDR_MR0 0x080032 /* MRS, CAS 3, Burst Length 4 */ +#define DMC_SDR_MR1 0x180032 +#define DMC_DDR_MR0 0x080162 +#define DMC_DDR_MR1 0x180162 +#define DMC_mDDR_MR0 0x080032 /* CAS 3, Burst Length 4 */ +#define DMC_mDDR_MR1 0x180032 +#define DMC_mSDR_EMR0 0x0a0000 /* EMRS, DS:Full, PASR:Full Array */ +#define DMC_mSDR_EMR1 0x1a0000 +#define DMC_DDR_EMR0 0x090000 +#define DMC_DDR_EMR1 0x190000 +#define DMC_mDDR_EMR0 0x0a0000 /* DS:Full, PASR:Full Array */ +#define DMC_mDDR_EMR1 0x1a0000 + +/**************************************************************** + Definitions for memory configuration + Set memory configuration + active_chips = 1'b0 (1 chip) + qos_master_chip = 3'b000(ARID[3:0]) + memory burst = 3'b010(burst 4) + stop_mem_clock = 1'b0(disable dynamical stop) + auto_power_down = 1'b0(disable auto power-down mode) + power_down_prd = 6'b00_0000(0 cycle for auto power-down) + ap_bit = 1'b0 (bit position of auto-precharge is 10) + row_bits = 3'b010(# row address 13) + column_bits = 3'b010(# column address 10 ) + + Set user configuration + 2'b10=SDRAM/mSDRAM, 2'b11=DDR, 2'b01=mDDR + + Set chip select for chip [n] + row bank control, bank address 0x3000_0000 ~ 0x37ff_ffff + CHIP_[n]_CFG=0x30F8, 30: ADDR[31:24], F8: Mask[31:24] +******************************************************************/ + +/* + * Nand flash controller + */ +#define ELFIN_NAND_BASE 0x70200000 + +#define NFCONF_OFFSET 0x00 +#define NFCONT_OFFSET 0x04 +#define NFCMMD_OFFSET 0x08 +#define NFADDR_OFFSET 0x0c +#define NFDATA_OFFSET 0x10 +#define NFMECCDATA0_OFFSET 0x14 +#define NFMECCDATA1_OFFSET 0x18 +#define NFSECCDATA0_OFFSET 0x1c +#define NFSBLK_OFFSET 0x20 +#define NFEBLK_OFFSET 0x24 +#define NFSTAT_OFFSET 0x28 +#define NFESTAT0_OFFSET 0x2c +#define NFESTAT1_OFFSET 0x30 +#define NFMECC0_OFFSET 0x34 +#define NFMECC1_OFFSET 0x38 +#define NFSECC_OFFSET 0x3c +#define NFMLCBITPT_OFFSET 0x40 + +#define NFCONF (ELFIN_NAND_BASE+NFCONF_OFFSET) +#define NFCONT (ELFIN_NAND_BASE+NFCONT_OFFSET) +#define NFCMMD (ELFIN_NAND_BASE+NFCMMD_OFFSET) +#define NFADDR (ELFIN_NAND_BASE+NFADDR_OFFSET) +#define NFDATA (ELFIN_NAND_BASE+NFDATA_OFFSET) +#define NFMECCDATA0 (ELFIN_NAND_BASE+NFMECCDATA0_OFFSET) +#define NFMECCDATA1 (ELFIN_NAND_BASE+NFMECCDATA1_OFFSET) +#define NFSECCDATA0 (ELFIN_NAND_BASE+NFSECCDATA0_OFFSET) +#define NFSBLK (ELFIN_NAND_BASE+NFSBLK_OFFSET) +#define NFEBLK (ELFIN_NAND_BASE+NFEBLK_OFFSET) +#define NFSTAT (ELFIN_NAND_BASE+NFSTAT_OFFSET) +#define NFESTAT0 (ELFIN_NAND_BASE+NFESTAT0_OFFSET) +#define NFESTAT1 (ELFIN_NAND_BASE+NFESTAT1_OFFSET) +#define NFMECC0 (ELFIN_NAND_BASE+NFMECC0_OFFSET) +#define NFMECC1 (ELFIN_NAND_BASE+NFMECC1_OFFSET) +#define NFSECC (ELFIN_NAND_BASE+NFSECC_OFFSET) +#define NFMLCBITPT (ELFIN_NAND_BASE+NFMLCBITPT_OFFSET) + +#define NFCONF_REG __REG(ELFIN_NAND_BASE+NFCONF_OFFSET) +#define NFCONT_REG __REG(ELFIN_NAND_BASE+NFCONT_OFFSET) +#define NFCMD_REG __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET) +#define NFADDR_REG __REG(ELFIN_NAND_BASE+NFADDR_OFFSET) +#define NFDATA_REG __REG(ELFIN_NAND_BASE+NFDATA_OFFSET) +#define NFDATA8_REG __REGb(ELFIN_NAND_BASE+NFDATA_OFFSET) +#define NFMECCDATA0_REG __REG(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET) +#define NFMECCDATA1_REG __REG(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET) +#define NFSECCDATA0_REG __REG(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET) +#define NFSBLK_REG __REG(ELFIN_NAND_BASE+NFSBLK_OFFSET) +#define NFEBLK_REG __REG(ELFIN_NAND_BASE+NFEBLK_OFFSET) +#define NFSTAT_REG __REG(ELFIN_NAND_BASE+NFSTAT_OFFSET) +#define NFESTAT0_REG __REG(ELFIN_NAND_BASE+NFESTAT0_OFFSET) +#define NFESTAT1_REG __REG(ELFIN_NAND_BASE+NFESTAT1_OFFSET) +#define NFMECC0_REG __REG(ELFIN_NAND_BASE+NFMECC0_OFFSET) +#define NFMECC1_REG __REG(ELFIN_NAND_BASE+NFMECC1_OFFSET) +#define NFSECC_REG __REG(ELFIN_NAND_BASE+NFSECC_OFFSET) +#define NFMLCBITPT_REG __REG(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET) + +#define NFCONF_ECC_4BIT (1<<24) + +#define NFCONT_ECC_ENC (1<<18) +#define NFCONT_WP (1<<16) +#define NFCONT_MECCLOCK (1<<7) +#define NFCONT_SECCLOCK (1<<6) +#define NFCONT_INITMECC (1<<5) +#define NFCONT_INITSECC (1<<4) +#define NFCONT_INITECC (NFCONT_INITMECC | NFCONT_INITSECC) +#define NFCONT_CS_ALT (1<<2) +#define NFCONT_CS (1<<1) +#define NFCONT_ENABLE (1<<0) + +#define NFSTAT_ECCENCDONE (1<<7) +#define NFSTAT_ECCDECDONE (1<<6) +#define NFSTAT_RnB (1<<0) + +#define NFESTAT0_ECCBUSY (1<<31) + +/* + * Interrupt + */ +#define ELFIN_VIC0_BASE_ADDR (0x71200000) +#define ELFIN_VIC1_BASE_ADDR (0x71300000) +#define oINTMOD (0x0C) /* VIC INT SELECT (IRQ or FIQ) */ +#define oINTUNMSK (0x10) /* VIC INT EN (Unmask by writing 1) */ +#define oINTMSK (0x14) /* VIC INT EN CLEAR (Mask by writing 1) */ +#define oINTSUBMSK (0x1C) /* VIC SOFT INT CLEAR */ +#define oVECTADDR (0xF00) /* VIC ADDRESS */ + +/* + * Watchdog timer + */ +#define ELFIN_WATCHDOG_BASE 0x7E004000 + +#define WTCON_REG __REG(0x7E004004) +#define WTDAT_REG __REG(0x7E004008) +#define WTCNT_REG __REG(0x7E00400C) + + +/* + * UART + */ +#define ELFIN_UART_BASE 0x7F005000 + +#define ELFIN_UART0_OFFSET 0x0000 +#define ELFIN_UART1_OFFSET 0x0400 +#define ELFIN_UART2_OFFSET 0x0800 + +#define ULCON_OFFSET 0x00 +#define UCON_OFFSET 0x04 +#define UFCON_OFFSET 0x08 +#define UMCON_OFFSET 0x0C +#define UTRSTAT_OFFSET 0x10 +#define UERSTAT_OFFSET 0x14 +#define UFSTAT_OFFSET 0x18 +#define UMSTAT_OFFSET 0x1C +#define UTXH_OFFSET 0x20 +#define URXH_OFFSET 0x24 +#define UBRDIV_OFFSET 0x28 +#define UDIVSLOT_OFFSET 0x2C +#define UINTP_OFFSET 0x30 +#define UINTSP_OFFSET 0x34 +#define UINTM_OFFSET 0x38 + +#define ULCON0_REG __REG(0x7F005000) +#define UCON0_REG __REG(0x7F005004) +#define UFCON0_REG __REG(0x7F005008) +#define UMCON0_REG __REG(0x7F00500C) +#define UTRSTAT0_REG __REG(0x7F005010) +#define UERSTAT0_REG __REG(0x7F005014) +#define UFSTAT0_REG __REG(0x7F005018) +#define UMSTAT0_REG __REG(0x7F00501c) +#define UTXH0_REG __REG(0x7F005020) +#define URXH0_REG __REG(0x7F005024) +#define UBRDIV0_REG __REG(0x7F005028) +#define UDIVSLOT0_REG __REG(0x7F00502c) +#define UINTP0_REG __REG(0x7F005030) +#define UINTSP0_REG __REG(0x7F005034) +#define UINTM0_REG __REG(0x7F005038) + +#define ULCON1_REG __REG(0x7F005400) +#define UCON1_REG __REG(0x7F005404) +#define UFCON1_REG __REG(0x7F005408) +#define UMCON1_REG __REG(0x7F00540C) +#define UTRSTAT1_REG __REG(0x7F005410) +#define UERSTAT1_REG __REG(0x7F005414) +#define UFSTAT1_REG __REG(0x7F005418) +#define UMSTAT1_REG __REG(0x7F00541c) +#define UTXH1_REG __REG(0x7F005420) +#define URXH1_REG __REG(0x7F005424) +#define UBRDIV1_REG __REG(0x7F005428) +#define UDIVSLOT1_REG __REG(0x7F00542c) +#define UINTP1_REG __REG(0x7F005430) +#define UINTSP1_REG __REG(0x7F005434) +#define UINTM1_REG __REG(0x7F005438) + +#define UTRSTAT_TX_EMPTY (1 << 2) +#define UTRSTAT_RX_READY (1 << 0) +#define UART_ERR_MASK 0xF + +/* + * PWM timer + */ +#define ELFIN_TIMER_BASE 0x7F006000 + +#define TCFG0_REG __REG(0x7F006000) +#define TCFG1_REG __REG(0x7F006004) +#define TCON_REG __REG(0x7F006008) +#define TCNTB0_REG __REG(0x7F00600c) +#define TCMPB0_REG __REG(0x7F006010) +#define TCNTO0_REG __REG(0x7F006014) +#define TCNTB1_REG __REG(0x7F006018) +#define TCMPB1_REG __REG(0x7F00601c) +#define TCNTO1_REG __REG(0x7F006020) +#define TCNTB2_REG __REG(0x7F006024) +#define TCMPB2_REG __REG(0x7F006028) +#define TCNTO2_REG __REG(0x7F00602c) +#define TCNTB3_REG __REG(0x7F006030) +#define TCMPB3_REG __REG(0x7F006034) +#define TCNTO3_REG __REG(0x7F006038) +#define TCNTB4_REG __REG(0x7F00603c) +#define TCNTO4_REG __REG(0x7F006040) + +/* Fields */ +#define fTCFG0_DZONE Fld(8,16) /* the dead zone length (= timer 0) */ +#define fTCFG0_PRE1 Fld(8,8) /* prescaler value for time 2,3,4 */ +#define fTCFG0_PRE0 Fld(8,0) /* prescaler value for time 0,1 */ +#define fTCFG1_MUX4 Fld(4,16) +/* bits */ +#define TCFG0_DZONE(x) FInsrt((x), fTCFG0_DZONE) +#define TCFG0_PRE1(x) FInsrt((x), fTCFG0_PRE1) +#define TCFG0_PRE0(x) FInsrt((x), fTCFG0_PRE0) +#define TCON_4_AUTO (1 << 22) /* auto reload on/off for Timer 4 */ +#define TCON_4_UPDATE (1 << 21) /* manual Update TCNTB4 */ +#define TCON_4_ONOFF (1 << 20) /* 0: Stop, 1: start Timer 4 */ +#define COUNT_4_ON (TCON_4_ONOFF*1) +#define COUNT_4_OFF (TCON_4_ONOFF*0) +#define TCON_3_AUTO (1 << 19) /* auto reload on/off for Timer 3 */ +#define TIMER3_ATLOAD_ON (TCON_3_AUTO*1) +#define TIMER3_ATLAOD_OFF FClrBit(TCON, TCON_3_AUTO) +#define TCON_3_INVERT (1 << 18) /* 1: Inverter on for TOUT3 */ +#define TIMER3_IVT_ON (TCON_3_INVERT*1) +#define TIMER3_IVT_OFF (FClrBit(TCON, TCON_3_INVERT)) +#define TCON_3_MAN (1 << 17) /* manual Update TCNTB3,TCMPB3 */ +#define TIMER3_MANUP (TCON_3_MAN*1) +#define TIMER3_NOP (FClrBit(TCON, TCON_3_MAN)) +#define TCON_3_ONOFF (1 << 16) /* 0: Stop, 1: start Timer 3 */ +#define TIMER3_ON (TCON_3_ONOFF*1) +#define TIMER3_OFF (FClrBit(TCON, TCON_3_ONOFF)) +/* macros */ +#define GET_PRESCALE_TIMER4(x) FExtr((x), fTCFG0_PRE1) +#define GET_DIVIDER_TIMER4(x) FExtr((x), fTCFG1_MUX4) + +/* include common stuff */ +#ifndef __ASSEMBLY__ + +#define NAND_DISABLE_CE() (NFCONT_REG |= (1 << 1)) +#define NAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1)) +#define NF_TRANSRnB() do { while (!(NFSTAT_REG & (1 << 0))); } while(0) + +static inline S3C64XX_UART * S3C64XX_GetBase_UART(S3C64XX_UARTS_NR nr) +{ + return (S3C64XX_UART *)(ELFIN_UART_BASE + (nr * 0x400)); +} + +static inline S3C64XX_TIMERS * S3C64XX_GetBase_TIMERS(void) +{ + return (S3C64XX_TIMERS *)ELFIN_TIMER_BASE; +} + +#else /* #ifndef __ASSEMBLY__ */ + +/* watchdog */ +#define WTCON_OFFSET 0x00 + +/* LCD controller */ +#define LCDBGCON_OFFSET 0x5c + +#endif /* #ifndef __ASSEMBLY__ */ + +#if defined(CONFIG_CLK_400_100_50) +#define Startup_AMDIV 400 +#define Startup_MDIV 400 +#define Startup_PDIV 6 +#define Startup_SDIV 1 +#elif defined(CONFIG_CLK_400_133_66) +#define Startup_AMDIV 400 +#define Startup_MDIV 533 +#define Startup_PDIV 6 +#define Startup_SDIV 1 +#elif defined(CONFIG_CLK_533_133_66) +#define Startup_AMDIV 533 +#define Startup_MDIV 533 +#define Startup_PDIV 6 +#define Startup_SDIV 1 +#elif defined(CONFIG_CLK_667_133_66) +#define Startup_AMDIV 667 +#define Startup_MDIV 533 +#define Startup_PDIV 6 +#define Startup_SDIV 1 +#endif + +#define Startup_PCLKdiv 3 +#define Startup_HCLKx2div 1 +#define Startup_HCLKdiv 1 +#define Startup_MPLLdiv 1 +#define Startup_APLLdiv 0 + +#define CLK_DIV_VAL ((Startup_PCLKdiv<<12)|(Startup_HCLKx2div<<9)|(Startup_HCLKdiv<<8)|(Startup_MPLLdiv<<4)|Startup_APLLdiv) +#define MPLL_VAL ((1<<31)|(Startup_MDIV<<16)|(Startup_PDIV<<8)|Startup_SDIV) +#define Startup_MPLL (((CONFIG_SYS_CLK_FREQ>>Startup_SDIV)/Startup_PDIV)*Startup_MDIV) + +#if defined(CONFIG_SYNC_MODE) +#define APLL_VAL ((1<<31)|(Startup_MDIV<<16)|(Startup_PDIV<<8)|Startup_SDIV) +#define Startup_APLL (((CONFIG_SYS_CLK_FREQ>>Startup_SDIV)/Startup_PDIV)*Startup_MDIV) +#define Startup_HCLK Startup_MPLL/(Startup_HCLKx2div+1)/(Startup_HCLKdiv+1) +#else +#define APLL_VAL ((1<<31)|(Startup_AMDIV<<16)|(Startup_PDIV<<8)|Startup_SDIV) +#define Startup_APLL (((CONFIG_SYS_CLK_FREQ>>Startup_SDIV)/Startup_PDIV)*Startup_AMDIV) +#define Startup_HCLK Startup_MPLL/(Startup_HCLKx2div+1)/(Startup_HCLKdiv+1) +#endif + + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define DMC1_MEM_CFG 0x80010012 /* Chip1, Burst4, Row/Column bit */ +#define DMC1_MEM_CFG2 0xB45 +#define DMC1_CHIP0_CFG 0x150F8 /* 0x4000_0000 ~ 0x43ff_ffff (64MB) */ +#define DMC_DDR_32_CFG 0x0 /* 32bit, DDR */ + +/* Memory Parameters */ +/* DDR Parameters */ +#define DDR_tREFRESH 7800 /* ns */ +#define DDR_tRAS 45 /* ns (min: 45ns)*/ +#define DDR_tRC 68 /* ns (min: 67.5ns)*/ +#define DDR_tRCD 23 /* ns (min: 22.5ns)*/ +#define DDR_tRFC 80 /* ns (min: 80ns)*/ +#define DDR_tRP 23 /* ns (min: 22.5ns)*/ +#define DDR_tRRD 15 /* ns (min: 15ns)*/ +#define DDR_tWR 15 /* ns (min: 15ns)*/ +#define DDR_tXSR 120 /* ns (min: 120ns)*/ +#define DDR_CASL 3 /* CAS Latency 3 */ + +/* + * mDDR memory configuration + */ +#define DMC_DDR_BA_EMRS 2 +#define DMC_DDR_MEM_CASLAT 3 +#define DMC_DDR_CAS_LATENCY (DDR_CASL<<1) /* 6 Set Cas Latency to 3 */ +#define DMC_DDR_t_DQSS 1 /* Min 0.75 ~ 1.25 */ +#define DMC_DDR_t_MRD 2 /* Min 2 tck */ +#define DMC_DDR_t_RAS (((Startup_HCLK/1000*DDR_tRAS)-1)/1000000+1) /* 7, Min 45ns */ +#define DMC_DDR_t_RC (((Startup_HCLK/1000*DDR_tRC)-1)/1000000+1) /* 10, Min 67.5ns */ +#define DMC_DDR_t_RCD (((Startup_HCLK/1000*DDR_tRCD)-1)/1000000+1) /* 4,5(TRM), Min 22.5ns */ +#define DMC_DDR_schedule_RCD ((DMC_DDR_t_RCD -3) <<3) +#define DMC_DDR_t_RFC (((Startup_HCLK/1000*DDR_tRFC)-1)/1000000+1) /* 11,18(TRM) Min 80ns */ +#define DMC_DDR_schedule_RFC ((DMC_DDR_t_RFC -3) <<5) +#define DMC_DDR_t_RP (((Startup_HCLK/1000*DDR_tRP)-1)/1000000+1) /* 4, 5(TRM) Min 22.5ns */ +#define DMC_DDR_schedule_RP ((DMC_DDR_t_RP -3) << 3) +#define DMC_DDR_t_RRD (((Startup_HCLK/1000*DDR_tRRD)-1)/1000000+1) /* 3, Min 15ns */ +#define DMC_DDR_t_WR (((Startup_HCLK/1000*DDR_tWR)-1)/1000000+1) /* Min 15ns */ +#define DMC_DDR_t_WTR 2 +#define DMC_DDR_t_XP 2 /* 1tck + tIS(1.5ns) */ +#define DMC_DDR_t_XSR (((Startup_HCLK/1000*DDR_tXSR)-1)/1000000+1) /* 17, Min 120ns */ +#define DMC_DDR_t_ESR DMC_DDR_t_XSR +#define DMC_DDR_REFRESH_PRD (((Startup_HCLK/1000*DDR_tREFRESH)-1)/1000000) /* TRM 2656 */ +#define DMC_DDR_USER_CONFIG 1 /* 2b01 : mDDR */ + +#endif /*__S3C6400_H__*/ diff --git a/include/s3c64x0.h b/include/s3c64x0.h new file mode 100644 index 0000000..3b84f50 --- /dev/null +++ b/include/s3c64x0.h @@ -0,0 +1,85 @@ +/* + * (C) Copyright 2003 + * David MÃŒller ELSOFT AG Switzerland. d.mueller@elsoft.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/************************************************ + * NAME : S3C64XX.h + * Version : 31.3.2003 + * + * common stuff for SAMSUNG S3C64XX SoC + ************************************************/ + +#ifndef __S3C64XX_H__ +#define __S3C64XX_H__ + +typedef vu_char S3C64XX_REG8; +typedef vu_short S3C64XX_REG16; +typedef vu_long S3C64XX_REG32; + +/* UART (see manual chapter 11) */ +typedef struct { + S3C64XX_REG32 ULCON; + S3C64XX_REG32 UCON; + S3C64XX_REG32 UFCON; + S3C64XX_REG32 UMCON; + S3C64XX_REG32 UTRSTAT; + S3C64XX_REG32 UERSTAT; + S3C64XX_REG32 UFSTAT; + S3C64XX_REG32 UMSTAT; +#ifdef __BIG_ENDIAN + S3C64XX_REG8 res1[3]; + S3C64XX_REG8 UTXH; + S3C64XX_REG8 res2[3]; + S3C64XX_REG8 URXH; +#else /* Little Endian */ + S3C64XX_REG8 UTXH; + S3C64XX_REG8 res1[3]; + S3C64XX_REG8 URXH; + S3C64XX_REG8 res2[3]; +#endif + S3C64XX_REG32 UBRDIV; +#ifdef __BIG_ENDIAN + S3C64XX_REG8 res3[2]; + S3C64XX_REG16 UDIVSLOT; +#else + S3C64XX_REG16 UDIVSLOT; + S3C64XX_REG8 res3[2]; +#endif +} /*__attribute__((__packed__))*/ S3C64XX_UART; + +/* PWM TIMER (see manual chapter 10) */ +typedef struct { + S3C64XX_REG32 TCNTB; + S3C64XX_REG32 TCMPB; + S3C64XX_REG32 TCNTO; +} /*__attribute__((__packed__))*/ S3C64XX_TIMER; + +typedef struct { + S3C64XX_REG32 TCFG0; + S3C64XX_REG32 TCFG1; + S3C64XX_REG32 TCON; + S3C64XX_TIMER ch[4]; + S3C64XX_REG32 TCNTB4; + S3C64XX_REG32 TCNTO4; +} /*__attribute__((__packed__))*/ S3C64XX_TIMERS; + +#endif /*__S3C64XX_H__*/

In message Pine.LNX.4.64.0807311242440.4832@axis700.grange you wrote:
This is a port of s3c6400 sources by Samsung from u-boot-1.1.6.
Signed-off-by: Guennadi Liakhovetski lg@denx.de
Coding style errors: indentation by space instead of TAB;
...
+/* * reset the cpu by setting up the watchdog timer and let him time out */ +void reset_cpu (ulong ignored) +{
- printf("reset... \n\n\n");
- SW_RST_REG = 0x6400;
- /* loop forever and wait for reset to happen */
- while (1)
- {
if (serial_tstc())
{
serial_getc();
break;
}
- }
Incorrect brace style.
...
diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile new file mode 100644 index 0000000..0a1201d --- /dev/null +++ b/cpu/arm1176/s3c64xx/Makefile @@ -0,0 +1,46 @@
...
+include $(TOPDIR)/config.mk
+LIB = $(obj)lib$(SOC).a
+OBJS = interrupts.o +#OBJS = nand_cp.o serial.o usb_ohci.o interrupts.o nand.o +COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o
+OBJS += $(COBJS-y)
+all: $(obj).depend $(START) $(LIB)
+$(LIB): $(OBJS)
- $(AR) $(ARFLAGS) $@ $(OBJS)
+#########################################################################
+# defines $(obj).depend target +include $(SRCTREE)/rules.mk
+sinclude .depend
Broken for out-of-tree building. This applies to all your Makefiles, I think.
Best regards,
Wolfgang Denk

+# 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., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
- -msoft-float
+# Make ARMv5 to allow more compilers to work, even though its v6. +PLATFORM_CPPFLAGS += -march=armv5t
could we do it dynamicly?
+# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) +PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c new file mode 100644 index 0000000..54228d1 --- /dev/null +++ b/cpu/arm1176/cpu.c @@ -0,0 +1,186 @@ +/*
- (C) Copyright 2004 Texas Insturments
- (C) Copyright 2002
- Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- Marius Groeger mgroeger@sysgo.de
- (C) Copyright 2002
- Gary Jennejohn, DENX Software Engineering, gj@denx.de
- See file CREDITS for list of people who contributed to this
- project.
+{
- volatile int i;
- /* Many OMAP regs need at least 2 nops */
so please use nop
- for (i = 0; i < 100; i++);
+}
+/* See also ARM Ref. Man. */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_DC (1<<2) /* dcache off/on */ +#define C1_WB (1<<3) /* merging write buffer on/off */ +#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_IC (1<<12) /* icache off/on */ +#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ +#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */
+int cpu_init (void) +{
- return 0;
+}
+int cleanup_before_linux (void) +{
- /*
* this function is called just before we call linux
* it prepares the processor for linux
*
* we turn off caches etc ...
*/
- unsigned long i;
- disable_interrupts ();
- /* turn off I/D-cache */
- asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
- i &= ~(C1_DC | C1_IC);
- asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
why don't you use icache_disable() and dcache_disable()?
- /* flush I/D-cache */
- i = 0;
- asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); /* invalidate both caches and flush btb */
- asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); /* mem barrier to sync things */
please implement icache_flush() and dcache_flush()
- return 0;
+}
+++ b/cpu/arm1176/s3c64xx/Makefile +#include <common.h> +#include <asm/proc-armv/ptrace.h> +#include <s3c6400.h>
+static ulong timer_load_val;
+#define PRESCALER 167
+/* macro to read the 16 bit timer */ +static inline ulong READ_TIMER(void) +{
- S3C64XX_TIMERS *const timers = S3C64XX_GetBase_TIMERS();
please do not use UPPERCASE var type and function & co
- return timers->TCNTO4;
+}
new file mode 100644 index 0000000..f28ebe8 --- /dev/null +++ b/cpu/arm1176/s3c64xx/nand_cp.c @@ -0,0 +1,132 @@ +/*
- $Id: nand_cp.c,v 1.3 2007/02/26 06:19:52 yongkal Exp $
please remove
- (C) Copyright 2006 Samsung Electronics
- See file CREDITS for list of people who contributed to this
- project.
- 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., 59 Temple Place, Suite 330, Boston,
- MA 02111-1307 USA
- */
please be carefull of the coding style too
Best Regards, J.
participants (3)
-
Guennadi Liakhovetski
-
Jean-Christophe PLAGNIOL-VILLARD
-
Wolfgang Denk