Skip to content
Snippets Groups Projects
Commit 9b07773f authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Jean-Christophe PLAGNIOL-VILLARD
Browse files

ARM: Add arm1176 core with S3C6400 SoC


Based on the original S3C64XX port by Samsung for U-Boot 1.1.6.

Signed-off-by: default avatarGuennadi Liakhovetski <lg@denx.de>
parent fcaac589
No related branches found
No related tags found
No related merge requests found
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2008
# Guennadi Liakhovetki, DENX Software Engineering, <lg@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
#########################################################################
#
# (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,))
/*
* (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>
static void cache_flush (void);
/* 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++)
__asm__ __volatile__("nop\n");
}
/* 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 */
#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 ...
*/
disable_interrupts ();
/* turn off I/D-cache */
icache_disable();
dcache_disable();
cache_flush();
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 ();
write_p15_c1 (reg & ~C1_DC);
}
int dcache_status (void)
{
return (read_p15_c1 () & C1_DC) != 0;
}
/* flush I/D-cache */
static void cache_flush (void)
{
/* invalidate both caches and flush btb */
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0));
/* mem barrier to sync things */
asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0));
}
#
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2008
# Guennadi Liakhovetki, DENX Software Engineering, <lg@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
COBJS-y = interrupts.o
COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################
#
# (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,))
/*
* Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
*
* Copyright (C) 2008
* Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <config.h>
#include <s3c6400.h>
.globl mem_ctrl_asm_init
mem_ctrl_asm_init:
/* Memory subsystem address 0x7e00f120 */
ldr r0, =ELFIN_MEM_SYS_CFG
/* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
mov r1, #0xd
str r1, [r0]
/* DMC1 base address 0x7e001000 */
ldr r0, =ELFIN_DMC1_BASE
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
.ltorg
/*
* (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>
*
* (C) Copyright 2008
* Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
#include <asm/proc-armv/ptrace.h>
#include <s3c6400.h>
static ulong timer_load_val;
#define PRESCALER 167
static s3c64xx_timers *s3c64xx_get_base_timers(void)
{
return (s3c64xx_timers *)ELFIN_TIMER_BASE;
}
/* macro to read the 16 bit timer */
static inline ulong read_timer(void)
{
s3c64xx_timers *const timers = s3c64xx_get_base_timers();
return timers->TCNTO4;
}
/* Internal tick units */
/* Last decremneter snapshot */
static unsigned long lastdec;
/* Monotonic incrementing timer */
static unsigned long long timestamp;
int interrupt_init(void)
{
s3c64xx_timers *const timers = s3c64xx_get_base_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.
*/
timers->TCFG0 = PRESCALER << 8;
if (timer_load_val == 0) {
timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */
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*/;
}
/*
* (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;
switch (pllreg) {
case APLL:
r = APLL_CON_REG;
break;
case MPLL:
r = MPLL_CON_REG;
break;
case EPLL:
r = EPLL_CON0_REG;
break;
default:
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;
/*
* Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on
* s3c6400 and is always 0, and it is indeed running in ASYNC mode
*/
if (OTHERS_REG & 0x80)
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 & 0x80)
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 & 0x80)
printf("(SYNC Mode) \n");
else
printf("(ASYNC Mode) \n");
return 0;
}
/*
* armboot - Startup Code for S3C6400/ARM1176 CPU-core
*
* Copyright (c) 2007 Samsung Electronics
*
* Copyright (C) 2008
* Guennadi Liakhovetki, DENX Software Engineering, <lg@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
*
* 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
/* We presume we're within the first 1024 bytes */
and r1, r1, #0x3fc
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
/* carve out a frame on current user stack */
sub sp, sp, #S_FRAME_SIZE
/* Save user registers (now in svc mode) r0-r12 */
stmia sp, {r0 - r12}
ldr r2, _armboot_start
sub r2, r2, #(CFG_MALLOC_LEN)
/* set base 2 words into abort stack */
sub r2, r2, #(CFG_GBL_DATA_SIZE+8)
/* get values for "aborted" pc and cpsr (into parm regs) */
ldmia r2, {r2 - r3}
/* grab pointer to old stack */
add r0, sp, #S_FRAME_SIZE
add r5, sp, #S_SP
mov r1, lr
/* save sp_SVC, lr_SVC, pc, cpsr */
stmia r5, {r0 - r3}
/* save current stack into r0 (param register) */
mov r0, sp
.endm
.macro get_bad_stack
/* setup our mode stack (enter in banked mode) */
ldr r13, _armboot_start
/* move past malloc pool */
sub r13, r13, #(CFG_MALLOC_LEN)
/* move to reserved a couple spots for abort stack */
sub r13, r13, #(CFG_GBL_DATA_SIZE + 8)
/* save caller lr in position 0 of saved stack */
str lr, [r13]
/* get the spsr */
mrs lr, spsr
/* save spsr in position 1 of saved stack */
str lr, [r13, #4]
/* prepare SVC-Mode */
mov r13, #MODE_SVC
@ msr spsr_c, r13
/* switch modes, make sure moves will execute */
msr spsr, r13
/* capture return pc */
mov lr, pc
/* jump to next instruction & switch modes. */
movs pc, lr
.endm
.macro get_bad_stack_swi
/* space on current stack for scratch reg. */
sub r13, r13, #4
/* save R0's value. */
str r0, [r13]
/* get data regions start */
ldr r0, _armboot_start
/* move past malloc pool */
sub r0, r0, #(CFG_MALLOC_LEN)
/* move past gbl and a couple spots for abort stack */
sub r0, r0, #(CFG_GBL_DATA_SIZE + 8)
/* save caller lr in position 0 of saved stack */
str lr, [r0]
/* get the spsr */
mrs r0, spsr
/* save spsr in position 1 of saved stack */
str lr, [r0, #4]
/* restore r0 */
ldr r0, [r13]
/* pop stack entry */
add r13, r13, #4
.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 */
/*
* Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
*
* (C) Copyright 2008
* Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
*
* 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
*/
#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_ */
......@@ -490,7 +490,8 @@ 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);
......
This diff is collapsed.
/*
* (C) Copyright 2003
* David MÃŒller ELSOFT AG Switzerland. d.mueller@elsoft.ch
*
* (C) Copyright 2008
* Guennadi Liakhovetki, DENX Software Engineering, <lg@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
*/
/************************************************
* NAME : S3C64XX.h
* Version : 31.3.2003
*
* common stuff for SAMSUNG S3C64XX SoC
************************************************/
#ifndef __S3C64XX_H__
#define __S3C64XX_H__
#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400)
#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your configuration!
#endif
#include <asm/types.h>
/* UART (see manual chapter 11) */
typedef struct {
volatile u32 ULCON;
volatile u32 UCON;
volatile u32 UFCON;
volatile u32 UMCON;
volatile u32 UTRSTAT;
volatile u32 UERSTAT;
volatile u32 UFSTAT;
volatile u32 UMSTAT;
#ifdef __BIG_ENDIAN
volatile u8 res1[3];
volatile u8 UTXH;
volatile u8 res2[3];
volatile u8 URXH;
#else /* Little Endian */
volatile u8 UTXH;
volatile u8 res1[3];
volatile u8 URXH;
volatile u8 res2[3];
#endif
volatile u32 UBRDIV;
#ifdef __BIG_ENDIAN
volatile u8 res3[2];
volatile u16 UDIVSLOT;
#else
volatile u16 UDIVSLOT;
volatile u8 res3[2];
#endif
} s3c64xx_uart;
/* PWM TIMER (see manual chapter 10) */
typedef struct {
volatile u32 TCNTB;
volatile u32 TCMPB;
volatile u32 TCNTO;
} s3c64xx_timer;
typedef struct {
volatile u32 TCFG0;
volatile u32 TCFG1;
volatile u32 TCON;
s3c64xx_timer ch[4];
volatile u32 TCNTB4;
volatile u32 TCNTO4;
} s3c64xx_timers;
#endif /*__S3C64XX_H__*/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment