mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add a directory by kernel instead of a common root, add qnap-301w and rpi4 kernel 6.1 suppport
This commit is contained in:
parent
e910436a7a
commit
46837ec4c0
9459 changed files with 362648 additions and 116345 deletions
2
common/package/utils/sysupgrade-helper/src/arch/.gitignore
vendored
Normal file
2
common/package/utils/sysupgrade-helper/src/arch/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/*/include/asm/arch
|
||||
/*/include/asm/proc
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
#
|
||||
# (C) Copyright 2000-2002
|
||||
# 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
|
||||
#
|
||||
|
||||
CROSS_COMPILE ?= arm-linux-
|
||||
|
||||
ifndef CONFIG_STANDALONE_LOAD_ADDR
|
||||
ifeq ($(SOC),omap3)
|
||||
CONFIG_STANDALONE_LOAD_ADDR = 0x80300000
|
||||
else
|
||||
CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
|
||||
endif
|
||||
endif
|
||||
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__ -fPIC
|
||||
|
||||
# Choose between ARM/Thumb instruction sets
|
||||
ifeq ($(CONFIG_SYS_THUMB_BUILD),y)
|
||||
PF_CPPFLAGS_ARM := $(call cc-option, -mthumb -mthumb-interwork,\
|
||||
$(call cc-option,-marm,)\
|
||||
$(call cc-option,-mno-thumb-interwork,)\
|
||||
)
|
||||
else
|
||||
PF_CPPFLAGS_ARM := $(call cc-option,-marm,) \
|
||||
$(call cc-option,-mno-thumb-interwork,)
|
||||
endif
|
||||
|
||||
# Only test once
|
||||
ifneq ($(CONFIG_SPL_BUILD),y)
|
||||
ALL-$(CONFIG_SYS_THUMB_BUILD) += checkthumb
|
||||
endif
|
||||
|
||||
# Try if EABI is supported, else fall back to old API,
|
||||
# i. e. for example:
|
||||
# - with ELDK 4.2 (EABI supported), use:
|
||||
# -mabi=aapcs-linux
|
||||
# - with ELDK 4.1 (gcc 4.x, no EABI), use:
|
||||
# -mabi=apcs-gnu
|
||||
# - with ELDK 3.1 (gcc 3.x), use:
|
||||
# -mapcs-32
|
||||
PF_CPPFLAGS_ABI := $(call cc-option,\
|
||||
-mabi=aapcs-linux,\
|
||||
$(call cc-option,\
|
||||
-mapcs-32,\
|
||||
$(call cc-option,\
|
||||
-mabi=apcs-gnu,\
|
||||
)\
|
||||
)\
|
||||
)
|
||||
PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARM) $(PF_CPPFLAGS_ABI)
|
||||
|
||||
# For EABI, make sure to provide raise()
|
||||
ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
|
||||
# This file is parsed many times, so the string may get added multiple
|
||||
# times. Also, the prefix needs to be different based on whether
|
||||
# CONFIG_SPL_BUILD is defined or not. 'filter-out' the existing entry
|
||||
# before adding the correct one.
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
PLATFORM_LIBS := $(SPLTREE)/arch/arm/lib/eabi_compat.o \
|
||||
$(filter-out %/arch/arm/lib/eabi_compat.o, $(PLATFORM_LIBS))
|
||||
else
|
||||
PLATFORM_LIBS := $(OBJTREE)/arch/arm/lib/eabi_compat.o \
|
||||
$(filter-out %/arch/arm/lib/eabi_compat.o, $(PLATFORM_LIBS))
|
||||
endif
|
||||
endif
|
||||
|
||||
# needed for relocation
|
||||
ifndef CONFIG_NAND_SPL
|
||||
LDFLAGS_u-boot += -pie
|
||||
endif
|
||||
|
|
@ -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).o
|
||||
|
||||
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)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@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-common -ffixed-r8 -msoft-float
|
||||
|
||||
# Make ARMv5 to allow more compilers to work, even though its v6.
|
||||
PLATFORM_CPPFLAGS += -march=armv5
|
||||
# =========================================================================
|
||||
#
|
||||
# Supply options according to compiler version
|
||||
#
|
||||
# =========================================================================
|
||||
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
|
||||
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* (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, <garyj@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 <asm/system.h>
|
||||
|
||||
static void cache_flush(void);
|
||||
|
||||
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 ();
|
||||
|
||||
#ifdef CONFIG_LCD
|
||||
{
|
||||
extern void lcd_disable(void);
|
||||
extern void lcd_panel_disable(void);
|
||||
|
||||
lcd_disable(); /* proper disable of lcd & panel */
|
||||
lcd_panel_disable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* turn off I/D-cache */
|
||||
icache_disable();
|
||||
dcache_disable();
|
||||
/* flush I/D-cache */
|
||||
cache_flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cache_flush(void)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
/* clean entire data cache */
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (i));
|
||||
/* invalidate both caches and flush btb */
|
||||
asm volatile("mcr p15, 0, %0, c7, c7, 0" : : "r" (i));
|
||||
/* mem barrier to sync things */
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (i));
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
|
||||
#ifndef CONFIG_SYS_CACHELINE_SIZE
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
#endif
|
||||
|
||||
void invalidate_dcache_all(void)
|
||||
{
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 0" : : "r" (0));
|
||||
}
|
||||
|
||||
void flush_dcache_all(void)
|
||||
{
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 0" : : "r" (0));
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
|
||||
}
|
||||
|
||||
static int check_cache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
int ok = 1;
|
||||
|
||||
if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
|
||||
ok = 0;
|
||||
|
||||
if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
|
||||
ok = 0;
|
||||
|
||||
if (!ok)
|
||||
debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
|
||||
start, stop);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void invalidate_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
if (!check_cache_range(start, stop))
|
||||
return;
|
||||
|
||||
while (start < stop) {
|
||||
asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (start));
|
||||
start += CONFIG_SYS_CACHELINE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void flush_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
if (!check_cache_range(start, stop))
|
||||
return;
|
||||
|
||||
while (start < stop) {
|
||||
asm volatile("mcr p15, 0, %0, c7, c14, 1" : : "r" (start));
|
||||
start += CONFIG_SYS_CACHELINE_SIZE;
|
||||
}
|
||||
|
||||
asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
|
||||
}
|
||||
|
||||
void flush_cache(unsigned long start, unsigned long size)
|
||||
{
|
||||
flush_dcache_range(start, start + size);
|
||||
}
|
||||
|
||||
void enable_caches(void)
|
||||
{
|
||||
#ifndef CONFIG_SYS_ICACHE_OFF
|
||||
icache_enable();
|
||||
#endif
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
dcache_enable();
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* #ifndef CONFIG_SYS_DCACHE_OFF */
|
||||
void invalidate_dcache_all(void)
|
||||
{
|
||||
}
|
||||
|
||||
void flush_dcache_all(void)
|
||||
{
|
||||
}
|
||||
|
||||
void invalidate_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
}
|
||||
|
||||
void flush_dcache_range(unsigned long start, unsigned long stop)
|
||||
{
|
||||
}
|
||||
|
||||
void flush_cache(unsigned long start, unsigned long size)
|
||||
{
|
||||
}
|
||||
#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
|
||||
|
|
@ -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$(SOC).o
|
||||
|
||||
COBJS += generic.o
|
||||
COBJS += timer.o
|
||||
COBJS += devices.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
*
|
||||
* (C) Copyright 2009 Magnus Lilja <lilja.magnus@gmail.com>
|
||||
*
|
||||
* (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.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/arch/imx-regs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
void mx31_uart1_hw_init(void)
|
||||
{
|
||||
/* setup pins for UART1 */
|
||||
mx31_gpio_mux(MUX_RXD1__UART1_RXD_MUX);
|
||||
mx31_gpio_mux(MUX_TXD1__UART1_TXD_MUX);
|
||||
mx31_gpio_mux(MUX_RTS1__UART1_RTS_B);
|
||||
mx31_gpio_mux(MUX_CTS1__UART1_CTS_B);
|
||||
}
|
||||
|
||||
void mx31_uart2_hw_init(void)
|
||||
{
|
||||
/* setup pins for UART2 */
|
||||
mx31_gpio_mux(MUX_RXD2__UART2_RXD_MUX);
|
||||
mx31_gpio_mux(MUX_TXD2__UART2_TXD_MUX);
|
||||
mx31_gpio_mux(MUX_RTS2__UART2_RTS_B);
|
||||
mx31_gpio_mux(MUX_CTS2__UART2_CTS_B);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MXC_SPI
|
||||
/*
|
||||
* Note: putting several spi setups here makes no sense as they may differ
|
||||
* at board level (physical pin SS0 of CSPI2 may aswell be used as SS0 of CSPI3)
|
||||
*/
|
||||
void mx31_spi2_hw_init(void)
|
||||
{
|
||||
/* SPI2 */
|
||||
mx31_gpio_mux(MUX_CSPI2_SS2__CSPI2_SS2_B);
|
||||
mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK);
|
||||
mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B);
|
||||
mx31_gpio_mux(MUX_CSPI2_MOSI__CSPI2_MOSI);
|
||||
mx31_gpio_mux(MUX_CSPI2_MISO__CSPI2_MISO);
|
||||
mx31_gpio_mux(MUX_CSPI2_SS0__CSPI2_SS0_B);
|
||||
mx31_gpio_mux(MUX_CSPI2_SS1__CSPI2_SS1_B);
|
||||
|
||||
/* start SPI2 clock */
|
||||
__REG(CCM_CGR2) = __REG(CCM_CGR2) | (3 << 4);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* 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/arch/imx-regs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
|
||||
static u32 mx31_decode_pll(u32 reg, u32 infreq)
|
||||
{
|
||||
u32 mfi = GET_PLL_MFI(reg);
|
||||
u32 mfn = GET_PLL_MFN(reg);
|
||||
u32 mfd = GET_PLL_MFD(reg);
|
||||
u32 pd = GET_PLL_PD(reg);
|
||||
|
||||
mfi = mfi <= 5 ? 5 : mfi;
|
||||
mfd += 1;
|
||||
pd += 1;
|
||||
|
||||
return ((2 * (infreq >> 10) * (mfi * mfd + mfn)) /
|
||||
(mfd * pd)) << 10;
|
||||
}
|
||||
|
||||
static u32 mx31_get_mpl_dpdgck_clk(void)
|
||||
{
|
||||
u32 infreq;
|
||||
|
||||
if ((readl(CCM_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM)
|
||||
infreq = CONFIG_MX31_CLK32 * 1024;
|
||||
else
|
||||
infreq = CONFIG_MX31_HCLK_FREQ;
|
||||
|
||||
return mx31_decode_pll(readl(CCM_MPCTL), infreq);
|
||||
}
|
||||
|
||||
static u32 mx31_get_mcu_main_clk(void)
|
||||
{
|
||||
/* For now we assume mpl_dpdgck_clk == mcu_main_clk
|
||||
* which should be correct for most boards
|
||||
*/
|
||||
return mx31_get_mpl_dpdgck_clk();
|
||||
}
|
||||
|
||||
static u32 mx31_get_ipg_clk(void)
|
||||
{
|
||||
u32 freq = mx31_get_mcu_main_clk();
|
||||
u32 pdr0 = readl(CCM_PDR0);
|
||||
|
||||
freq /= GET_PDR0_MAX_PODF(pdr0) + 1;
|
||||
freq /= GET_PDR0_IPG_PODF(pdr0) + 1;
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
/* hsp is the clock for the ipu */
|
||||
static u32 mx31_get_hsp_clk(void)
|
||||
{
|
||||
u32 freq = mx31_get_mcu_main_clk();
|
||||
u32 pdr0 = readl(CCM_PDR0);
|
||||
|
||||
freq /= GET_PDR0_HSP_PODF(pdr0) + 1;
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
void mx31_dump_clocks(void)
|
||||
{
|
||||
u32 cpufreq = mx31_get_mcu_main_clk();
|
||||
printf("mx31 cpu clock: %dMHz\n", cpufreq / 1000000);
|
||||
printf("ipg clock : %dHz\n", mx31_get_ipg_clk());
|
||||
printf("hsp clock : %dHz\n", mx31_get_hsp_clk());
|
||||
}
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_ARM_CLK:
|
||||
return mx31_get_mcu_main_clk();
|
||||
case MXC_IPG_CLK:
|
||||
case MXC_IPG_PERCLK:
|
||||
case MXC_CSPI_CLK:
|
||||
case MXC_UART_CLK:
|
||||
case MXC_ESDHC_CLK:
|
||||
return mx31_get_ipg_clk();
|
||||
case MXC_IPU_CLK:
|
||||
return mx31_get_hsp_clk();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 imx_get_uartclk(void)
|
||||
{
|
||||
return mxc_get_clock(MXC_UART_CLK);
|
||||
}
|
||||
|
||||
void mx31_gpio_mux(unsigned long mode)
|
||||
{
|
||||
unsigned long reg, shift, tmp;
|
||||
|
||||
reg = IOMUXC_BASE + (mode & 0x1fc);
|
||||
shift = (~mode & 0x3) * 8;
|
||||
|
||||
tmp = readl(reg);
|
||||
tmp &= ~(0xff << shift);
|
||||
tmp |= ((mode >> IOMUX_MODE_POS) & 0xff) << shift;
|
||||
writel(tmp, reg);
|
||||
}
|
||||
|
||||
void mx31_set_pad(enum iomux_pins pin, u32 config)
|
||||
{
|
||||
u32 field, l, reg;
|
||||
|
||||
pin &= IOMUX_PADNUM_MASK;
|
||||
reg = (IOMUXC_BASE + 0x154) + (pin + 2) / 3 * 4;
|
||||
field = (pin + 2) % 3;
|
||||
|
||||
l = readl(reg);
|
||||
l &= ~(0x1ff << (field * 10));
|
||||
l |= config << (field * 10);
|
||||
writel(l, reg);
|
||||
|
||||
}
|
||||
|
||||
void mx31_set_gpr(enum iomux_gp_func gp, char en)
|
||||
{
|
||||
u32 l;
|
||||
struct iomuxc_regs *iomuxc = (struct iomuxc_regs *)IOMUXC_BASE;
|
||||
|
||||
l = readl(&iomuxc->gpr);
|
||||
if (en)
|
||||
l |= gp;
|
||||
else
|
||||
l &= ~gp;
|
||||
|
||||
writel(l, &iomuxc->gpr);
|
||||
}
|
||||
|
||||
void mxc_setup_weimcs(int cs, const struct mxc_weimcs *weimcs)
|
||||
{
|
||||
struct mx31_weim *weim = (struct mx31_weim *) WEIM_BASE;
|
||||
struct mx31_weim_cscr *cscr = &weim->cscr[cs];
|
||||
|
||||
writel(weimcs->upper, &cscr->upper);
|
||||
writel(weimcs->lower, &cscr->lower);
|
||||
writel(weimcs->additional, &cscr->additional);
|
||||
}
|
||||
|
||||
struct mx3_cpu_type mx31_cpu_type[] = {
|
||||
{ .srev = 0x00, .v = 0x10 },
|
||||
{ .srev = 0x10, .v = 0x11 },
|
||||
{ .srev = 0x11, .v = 0x11 },
|
||||
{ .srev = 0x12, .v = 0x1F },
|
||||
{ .srev = 0x13, .v = 0x1F },
|
||||
{ .srev = 0x14, .v = 0x12 },
|
||||
{ .srev = 0x15, .v = 0x12 },
|
||||
{ .srev = 0x28, .v = 0x20 },
|
||||
{ .srev = 0x29, .v = 0x20 },
|
||||
};
|
||||
|
||||
u32 get_cpu_rev(void)
|
||||
{
|
||||
u32 i, srev;
|
||||
|
||||
/* read SREV register from IIM module */
|
||||
struct iim_regs *iim = (struct iim_regs *)MX31_IIM_BASE_ADDR;
|
||||
srev = readl(&iim->iim_srev);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
|
||||
if (srev == mx31_cpu_type[i].srev)
|
||||
return mx31_cpu_type[i].v;
|
||||
|
||||
return srev | 0x8000;
|
||||
}
|
||||
|
||||
static char *get_reset_cause(void)
|
||||
{
|
||||
/* read RCSR register from CCM module */
|
||||
struct clock_control_regs *ccm =
|
||||
(struct clock_control_regs *)CCM_BASE;
|
||||
|
||||
u32 cause = readl(&ccm->rcsr) & 0x07;
|
||||
|
||||
switch (cause) {
|
||||
case 0x0000:
|
||||
return "POR";
|
||||
case 0x0001:
|
||||
return "RST";
|
||||
case 0x0002:
|
||||
return "WDOG";
|
||||
case 0x0006:
|
||||
return "JTAG";
|
||||
case 0x0007:
|
||||
return "ARM11P power gating";
|
||||
default:
|
||||
return "unknown reset";
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
u32 srev = get_cpu_rev();
|
||||
|
||||
printf("CPU: Freescale i.MX31 rev %d.%d%s at %d MHz.\n",
|
||||
(srev & 0xF0) >> 4, (srev & 0x0F),
|
||||
((srev & 0x8000) ? " unknown" : ""),
|
||||
mx31_get_mcu_main_clk() / 1000000);
|
||||
printf("Reset cause: %s\n", get_reset_cause());
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* 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/arch/imx-regs.h>
|
||||
#include <div64.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define TIMER_BASE 0x53f90000 /* General purpose timer 1 */
|
||||
|
||||
/* General purpose timers registers */
|
||||
#define GPTCR __REG(TIMER_BASE) /* Control register */
|
||||
#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */
|
||||
#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */
|
||||
#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */
|
||||
|
||||
/* General purpose timers bitfields */
|
||||
#define GPTCR_SWR (1 << 15) /* Software reset */
|
||||
#define GPTCR_FRR (1 << 9) /* Freerun / restart */
|
||||
#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */
|
||||
#define GPTCR_TEN 1 /* Timer enable */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* "time" is measured in 1 / CONFIG_SYS_HZ seconds,
|
||||
* "tick" is internal timer period
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MX31_TIMER_HIGH_PRECISION
|
||||
/* ~0.4% error - measured with stop-watch on 100s boot-delay */
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
tick *= CONFIG_SYS_HZ;
|
||||
do_div(tick, CONFIG_MX31_CLK32);
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long time_to_tick(unsigned long long time)
|
||||
{
|
||||
time *= CONFIG_MX31_CLK32;
|
||||
do_div(time, CONFIG_SYS_HZ);
|
||||
return time;
|
||||
}
|
||||
|
||||
static inline unsigned long long us_to_tick(unsigned long long us)
|
||||
{
|
||||
us = us * CONFIG_MX31_CLK32 + 999999;
|
||||
do_div(us, 1000000);
|
||||
return us;
|
||||
}
|
||||
#else
|
||||
/* ~2% error */
|
||||
#define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) \
|
||||
/ CONFIG_SYS_HZ)
|
||||
#define US_PER_TICK (1000000 / CONFIG_MX31_CLK32)
|
||||
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
do_div(tick, TICK_PER_TIME);
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long time_to_tick(unsigned long long time)
|
||||
{
|
||||
return time * TICK_PER_TIME;
|
||||
}
|
||||
|
||||
static inline unsigned long long us_to_tick(unsigned long long us)
|
||||
{
|
||||
us += US_PER_TICK - 1;
|
||||
do_div(us, US_PER_TICK);
|
||||
return us;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The 32768Hz 32-bit timer overruns in 131072 seconds */
|
||||
int timer_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* setup GP Timer 1 */
|
||||
GPTCR = GPTCR_SWR;
|
||||
for (i = 0; i < 100; i++)
|
||||
GPTCR = 0; /* We have no udelay by now */
|
||||
GPTPR = 0; /* 32Khz */
|
||||
/* Freerun Mode, PERCLK1 input */
|
||||
GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
ulong now = GPTCNT; /* current tick value */
|
||||
|
||||
if (now >= gd->lastinc) /* normal mode (non roll) */
|
||||
/* move stamp forward with absolut diff ticks */
|
||||
gd->tbl += (now - gd->lastinc);
|
||||
else /* we have rollover of incrementer */
|
||||
gd->tbl += (0xFFFFFFFF - gd->lastinc) + now;
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
/*
|
||||
* get_ticks() returns a long long (64 bit), it wraps in
|
||||
* 2^64 / CONFIG_MX31_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
|
||||
* 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
|
||||
* 5 * 10^6 days - long enough.
|
||||
*/
|
||||
return tick_to_time(get_ticks());
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
/* delay x useconds AND preserve advance timestamp value */
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
unsigned long long tmp;
|
||||
ulong tmo;
|
||||
|
||||
tmo = us_to_tick(usec);
|
||||
tmp = get_ticks() + tmo; /* get current timestamp */
|
||||
|
||||
while (get_ticks() < tmp) /* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return CONFIG_MX31_CLK32;
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE;
|
||||
wdog->wcr = WDOG_ENABLE;
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HW_WATCHDOG
|
||||
void mxc_hw_watchdog_enable(void)
|
||||
{
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE;
|
||||
u16 secs;
|
||||
|
||||
/*
|
||||
* The timer watchdog can be set between
|
||||
* 0.5 and 128 Seconds. If not defined
|
||||
* in configuration file, sets 64 Seconds
|
||||
*/
|
||||
#ifdef CONFIG_SYS_WD_TIMER_SECS
|
||||
secs = (CONFIG_SYS_WD_TIMER_SECS << 1) & 0xFF;
|
||||
if (!secs) secs = 1;
|
||||
#else
|
||||
secs = 64;
|
||||
#endif
|
||||
setbits_le16(&wdog->wcr, (secs << WDOG_WT_SHIFT) | WDOG_ENABLE
|
||||
| WDOG_WDZST);
|
||||
}
|
||||
|
||||
|
||||
void mxc_hw_watchdog_reset(void)
|
||||
{
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE;
|
||||
|
||||
writew(0x5555, &wdog->wsr);
|
||||
writew(0xAAAA, &wdog->wsr);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# 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).o
|
||||
|
||||
COBJS += generic.o
|
||||
COBJS += timer.o
|
||||
COBJS += iomux.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c
|
||||
*
|
||||
* This program is used to generate definitions needed by
|
||||
* assembly language modules.
|
||||
*
|
||||
* We use the technique used in the OSF Mach kernel code:
|
||||
* generate asm statements containing #defines,
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
#include <linux/kbuild.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* Round up to make sure size gives nice stack alignment */
|
||||
DEFINE(CLKCTL_CCMR, offsetof(struct ccm_regs, ccmr));
|
||||
DEFINE(CLKCTL_PDR0, offsetof(struct ccm_regs, pdr0));
|
||||
DEFINE(CLKCTL_PDR1, offsetof(struct ccm_regs, pdr1));
|
||||
DEFINE(CLKCTL_PDR2, offsetof(struct ccm_regs, pdr2));
|
||||
DEFINE(CLKCTL_PDR3, offsetof(struct ccm_regs, pdr3));
|
||||
DEFINE(CLKCTL_PDR4, offsetof(struct ccm_regs, pdr4));
|
||||
DEFINE(CLKCTL_RCSR, offsetof(struct ccm_regs, rcsr));
|
||||
DEFINE(CLKCTL_MPCTL, offsetof(struct ccm_regs, mpctl));
|
||||
DEFINE(CLKCTL_PPCTL, offsetof(struct ccm_regs, ppctl));
|
||||
DEFINE(CLKCTL_ACMR, offsetof(struct ccm_regs, acmr));
|
||||
DEFINE(CLKCTL_COSR, offsetof(struct ccm_regs, cosr));
|
||||
DEFINE(CLKCTL_CGR0, offsetof(struct ccm_regs, cgr0));
|
||||
DEFINE(CLKCTL_CGR1, offsetof(struct ccm_regs, cgr1));
|
||||
DEFINE(CLKCTL_CGR2, offsetof(struct ccm_regs, cgr2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,490 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/crm_regs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <netdev.h>
|
||||
|
||||
#define CLK_CODE(arm, ahb, sel) (((arm) << 16) + ((ahb) << 8) + (sel))
|
||||
#define CLK_CODE_ARM(c) (((c) >> 16) & 0xFF)
|
||||
#define CLK_CODE_AHB(c) (((c) >> 8) & 0xFF)
|
||||
#define CLK_CODE_PATH(c) ((c) & 0xFF)
|
||||
|
||||
#define CCM_GET_DIVIDER(x, m, o) (((x) & (m)) >> (o))
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#endif
|
||||
|
||||
static int g_clk_mux_auto[8] = {
|
||||
CLK_CODE(1, 3, 0), CLK_CODE(1, 2, 1), CLK_CODE(2, 1, 1), -1,
|
||||
CLK_CODE(1, 6, 0), CLK_CODE(1, 4, 1), CLK_CODE(2, 2, 1), -1,
|
||||
};
|
||||
|
||||
static int g_clk_mux_consumer[16] = {
|
||||
CLK_CODE(1, 4, 0), CLK_CODE(1, 3, 1), CLK_CODE(1, 3, 1), -1,
|
||||
-1, -1, CLK_CODE(4, 1, 0), CLK_CODE(1, 5, 0),
|
||||
CLK_CODE(1, 8, 1), CLK_CODE(1, 6, 1), CLK_CODE(2, 4, 0), -1,
|
||||
-1, -1, CLK_CODE(4, 2, 0), -1,
|
||||
};
|
||||
|
||||
static int hsp_div_table[3][16] = {
|
||||
{4, 3, 2, -1, -1, -1, 1, 5, 4, 3, 2, -1, -1, -1, 1, -1},
|
||||
{-1, -1, -1, -1, -1, -1, -1, -1, 8, 6, 4, -1, -1, -1, 2, -1},
|
||||
{3, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
u32 get_cpu_rev(void)
|
||||
{
|
||||
int reg;
|
||||
struct iim_regs *iim =
|
||||
(struct iim_regs *)IIM_BASE_ADDR;
|
||||
reg = readl(&iim->iim_srev);
|
||||
if (!reg) {
|
||||
reg = readw(ROMPATCH_REV);
|
||||
reg <<= 4;
|
||||
} else {
|
||||
reg += CHIP_REV_1_0;
|
||||
}
|
||||
|
||||
return 0x35000 + (reg & 0xFF);
|
||||
}
|
||||
|
||||
static u32 get_arm_div(u32 pdr0, u32 *fi, u32 *fd)
|
||||
{
|
||||
int *pclk_mux;
|
||||
if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
|
||||
pclk_mux = g_clk_mux_consumer +
|
||||
((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
|
||||
MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
|
||||
} else {
|
||||
pclk_mux = g_clk_mux_auto +
|
||||
((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >>
|
||||
MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET);
|
||||
}
|
||||
|
||||
if ((*pclk_mux) == -1)
|
||||
return -1;
|
||||
|
||||
if (fi && fd) {
|
||||
if (!CLK_CODE_PATH(*pclk_mux)) {
|
||||
*fi = *fd = 1;
|
||||
return CLK_CODE_ARM(*pclk_mux);
|
||||
}
|
||||
if (pdr0 & MXC_CCM_PDR0_AUTO_CON) {
|
||||
*fi = 3;
|
||||
*fd = 4;
|
||||
} else {
|
||||
*fi = 2;
|
||||
*fd = 3;
|
||||
}
|
||||
}
|
||||
return CLK_CODE_ARM(*pclk_mux);
|
||||
}
|
||||
|
||||
static int get_ahb_div(u32 pdr0)
|
||||
{
|
||||
int *pclk_mux;
|
||||
|
||||
pclk_mux = g_clk_mux_consumer +
|
||||
((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
|
||||
MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
|
||||
|
||||
if ((*pclk_mux) == -1)
|
||||
return -1;
|
||||
|
||||
return CLK_CODE_AHB(*pclk_mux);
|
||||
}
|
||||
|
||||
static u32 decode_pll(u32 reg, u32 infreq)
|
||||
{
|
||||
u32 mfi = (reg >> 10) & 0xf;
|
||||
u32 mfn = reg & 0x3f;
|
||||
u32 mfd = (reg >> 16) & 0x3f;
|
||||
u32 pd = (reg >> 26) & 0xf;
|
||||
|
||||
mfi = mfi <= 5 ? 5 : mfi;
|
||||
mfd += 1;
|
||||
pd += 1;
|
||||
|
||||
return ((2 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000;
|
||||
}
|
||||
|
||||
static u32 get_mcu_main_clk(void)
|
||||
{
|
||||
u32 arm_div = 0, fi = 0, fd = 0;
|
||||
struct ccm_regs *ccm =
|
||||
(struct ccm_regs *)IMX_CCM_BASE;
|
||||
arm_div = get_arm_div(readl(&ccm->pdr0), &fi, &fd);
|
||||
fi *=
|
||||
decode_pll(readl(&ccm->mpctl),
|
||||
CONFIG_MX35_HCLK_FREQ);
|
||||
return fi / (arm_div * fd);
|
||||
}
|
||||
|
||||
static u32 get_ipg_clk(void)
|
||||
{
|
||||
u32 freq = get_mcu_main_clk();
|
||||
struct ccm_regs *ccm =
|
||||
(struct ccm_regs *)IMX_CCM_BASE;
|
||||
u32 pdr0 = readl(&ccm->pdr0);
|
||||
|
||||
return freq / (get_ahb_div(pdr0) * 2);
|
||||
}
|
||||
|
||||
static u32 get_ipg_per_clk(void)
|
||||
{
|
||||
u32 freq = get_mcu_main_clk();
|
||||
struct ccm_regs *ccm =
|
||||
(struct ccm_regs *)IMX_CCM_BASE;
|
||||
u32 pdr0 = readl(&ccm->pdr0);
|
||||
u32 pdr4 = readl(&ccm->pdr4);
|
||||
u32 div;
|
||||
if (pdr0 & MXC_CCM_PDR0_PER_SEL) {
|
||||
div = (CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_PER0_PRDF_MASK,
|
||||
MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1) *
|
||||
(CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_PER0_PODF_MASK,
|
||||
MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1);
|
||||
} else {
|
||||
div = CCM_GET_DIVIDER(pdr0,
|
||||
MXC_CCM_PDR0_PER_PODF_MASK,
|
||||
MXC_CCM_PDR0_PER_PODF_OFFSET) + 1;
|
||||
freq /= get_ahb_div(pdr0);
|
||||
}
|
||||
return freq / div;
|
||||
}
|
||||
|
||||
u32 imx_get_uartclk(void)
|
||||
{
|
||||
u32 freq;
|
||||
struct ccm_regs *ccm =
|
||||
(struct ccm_regs *)IMX_CCM_BASE;
|
||||
u32 pdr4 = readl(&ccm->pdr4);
|
||||
|
||||
if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U) {
|
||||
freq = get_mcu_main_clk();
|
||||
} else {
|
||||
freq = decode_pll(readl(&ccm->ppctl),
|
||||
CONFIG_MX35_HCLK_FREQ);
|
||||
}
|
||||
freq /= ((CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_UART_PRDF_MASK,
|
||||
MXC_CCM_PDR4_UART_PRDF_OFFSET) + 1) *
|
||||
(CCM_GET_DIVIDER(pdr4,
|
||||
MXC_CCM_PDR4_UART_PODF_MASK,
|
||||
MXC_CCM_PDR4_UART_PODF_OFFSET) + 1));
|
||||
return freq;
|
||||
}
|
||||
|
||||
unsigned int mxc_get_main_clock(enum mxc_main_clocks clk)
|
||||
{
|
||||
u32 nfc_pdf, hsp_podf;
|
||||
u32 pll, ret_val = 0, usb_prdf, usb_podf;
|
||||
struct ccm_regs *ccm =
|
||||
(struct ccm_regs *)IMX_CCM_BASE;
|
||||
|
||||
u32 reg = readl(&ccm->pdr0);
|
||||
u32 reg4 = readl(&ccm->pdr4);
|
||||
|
||||
reg |= 0x1;
|
||||
|
||||
switch (clk) {
|
||||
case CPU_CLK:
|
||||
ret_val = get_mcu_main_clk();
|
||||
break;
|
||||
case AHB_CLK:
|
||||
ret_val = get_mcu_main_clk();
|
||||
break;
|
||||
case HSP_CLK:
|
||||
if (reg & CLKMODE_CONSUMER) {
|
||||
hsp_podf = (reg >> 20) & 0x3;
|
||||
pll = get_mcu_main_clk();
|
||||
hsp_podf = hsp_div_table[hsp_podf][(reg>>16)&0xF];
|
||||
if (hsp_podf > 0) {
|
||||
ret_val = pll / hsp_podf;
|
||||
} else {
|
||||
puts("mismatch HSP with ARM clock setting\n");
|
||||
ret_val = 0;
|
||||
}
|
||||
} else {
|
||||
ret_val = get_mcu_main_clk();
|
||||
}
|
||||
break;
|
||||
case IPG_CLK:
|
||||
ret_val = get_ipg_clk();
|
||||
break;
|
||||
case IPG_PER_CLK:
|
||||
ret_val = get_ipg_per_clk();
|
||||
break;
|
||||
case NFC_CLK:
|
||||
nfc_pdf = (reg4 >> 28) & 0xF;
|
||||
pll = get_mcu_main_clk();
|
||||
/* AHB/nfc_pdf */
|
||||
ret_val = pll / (nfc_pdf + 1);
|
||||
break;
|
||||
case USB_CLK:
|
||||
usb_prdf = (reg4 >> 25) & 0x7;
|
||||
usb_podf = (reg4 >> 22) & 0x7;
|
||||
if (reg4 & 0x200) {
|
||||
pll = get_mcu_main_clk();
|
||||
} else {
|
||||
pll = decode_pll(readl(&ccm->ppctl),
|
||||
CONFIG_MX35_HCLK_FREQ);
|
||||
}
|
||||
|
||||
ret_val = pll / ((usb_prdf + 1) * (usb_podf + 1));
|
||||
break;
|
||||
default:
|
||||
printf("Unknown clock: %d\n", clk);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
unsigned int mxc_get_peri_clock(enum mxc_peri_clocks clk)
|
||||
{
|
||||
u32 ret_val = 0, pdf, pre_pdf, clk_sel;
|
||||
struct ccm_regs *ccm =
|
||||
(struct ccm_regs *)IMX_CCM_BASE;
|
||||
u32 mpdr2 = readl(&ccm->pdr2);
|
||||
u32 mpdr3 = readl(&ccm->pdr3);
|
||||
u32 mpdr4 = readl(&ccm->pdr4);
|
||||
|
||||
switch (clk) {
|
||||
case UART1_BAUD:
|
||||
case UART2_BAUD:
|
||||
case UART3_BAUD:
|
||||
clk_sel = mpdr3 & (1 << 14);
|
||||
pre_pdf = (mpdr4 >> 13) & 0x7;
|
||||
pdf = (mpdr4 >> 10) & 0x7;
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case SSI1_BAUD:
|
||||
pre_pdf = (mpdr2 >> 24) & 0x7;
|
||||
pdf = mpdr2 & 0x3F;
|
||||
clk_sel = mpdr2 & (1 << 6);
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case SSI2_BAUD:
|
||||
pre_pdf = (mpdr2 >> 27) & 0x7;
|
||||
pdf = (mpdr2 >> 8) & 0x3F;
|
||||
clk_sel = mpdr2 & (1 << 6);
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case CSI_BAUD:
|
||||
clk_sel = mpdr2 & (1 << 7);
|
||||
pre_pdf = (mpdr2 >> 16) & 0x7;
|
||||
pdf = (mpdr2 >> 19) & 0x7;
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case MSHC_CLK:
|
||||
pre_pdf = readl(&ccm->pdr1);
|
||||
clk_sel = (pre_pdf & 0x80);
|
||||
pdf = (pre_pdf >> 22) & 0x3F;
|
||||
pre_pdf = (pre_pdf >> 28) & 0x7;
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case ESDHC1_CLK:
|
||||
clk_sel = mpdr3 & 0x40;
|
||||
pre_pdf = mpdr3 & 0x7;
|
||||
pdf = (mpdr3>>3) & 0x7;
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case ESDHC2_CLK:
|
||||
clk_sel = mpdr3 & 0x40;
|
||||
pre_pdf = (mpdr3 >> 8) & 0x7;
|
||||
pdf = (mpdr3 >> 11) & 0x7;
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case ESDHC3_CLK:
|
||||
clk_sel = mpdr3 & 0x40;
|
||||
pre_pdf = (mpdr3 >> 16) & 0x7;
|
||||
pdf = (mpdr3 >> 19) & 0x7;
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
case SPDIF_CLK:
|
||||
clk_sel = mpdr3 & 0x400000;
|
||||
pre_pdf = (mpdr3 >> 29) & 0x7;
|
||||
pdf = (mpdr3 >> 23) & 0x3F;
|
||||
ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) :
|
||||
decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) /
|
||||
((pre_pdf + 1) * (pdf + 1));
|
||||
break;
|
||||
default:
|
||||
printf("%s(): This clock: %d not supported yet\n",
|
||||
__func__, clk);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_ARM_CLK:
|
||||
return get_mcu_main_clk();
|
||||
case MXC_AHB_CLK:
|
||||
break;
|
||||
case MXC_IPG_CLK:
|
||||
return get_ipg_clk();
|
||||
case MXC_IPG_PERCLK:
|
||||
return get_ipg_per_clk();
|
||||
case MXC_UART_CLK:
|
||||
return imx_get_uartclk();
|
||||
case MXC_ESDHC_CLK:
|
||||
return mxc_get_peri_clock(ESDHC1_CLK);
|
||||
case MXC_USB_CLK:
|
||||
return mxc_get_main_clock(USB_CLK);
|
||||
case MXC_FEC_CLK:
|
||||
return get_ipg_clk();
|
||||
case MXC_CSPI_CLK:
|
||||
return get_ipg_clk();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FEC_MXC
|
||||
/*
|
||||
* The MX35 has no fuse for MAC, return a NULL MAC
|
||||
*/
|
||||
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
|
||||
{
|
||||
memset(mac, 0, 6);
|
||||
}
|
||||
|
||||
u32 imx_get_fecclk(void)
|
||||
{
|
||||
return mxc_get_clock(MXC_IPG_CLK);
|
||||
}
|
||||
#endif
|
||||
|
||||
int do_mx35_showclocks(cmd_tbl_t *cmdtp,
|
||||
int flag, int argc, char * const argv[])
|
||||
{
|
||||
u32 cpufreq = get_mcu_main_clk();
|
||||
printf("mx35 cpu clock: %dMHz\n", cpufreq / 1000000);
|
||||
printf("ipg clock : %dHz\n", get_ipg_clk());
|
||||
printf("ipg per clock : %dHz\n", get_ipg_per_clk());
|
||||
printf("uart clock : %dHz\n", mxc_get_clock(MXC_UART_CLK));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
clocks, CONFIG_SYS_MAXARGS, 1, do_mx35_showclocks,
|
||||
"display clocks",
|
||||
""
|
||||
);
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
static char *get_reset_cause(void)
|
||||
{
|
||||
/* read RCSR register from CCM module */
|
||||
struct ccm_regs *ccm =
|
||||
(struct ccm_regs *)IMX_CCM_BASE;
|
||||
|
||||
u32 cause = readl(&ccm->rcsr) & 0x0F;
|
||||
|
||||
switch (cause) {
|
||||
case 0x0000:
|
||||
return "POR";
|
||||
case 0x0002:
|
||||
return "JTAG";
|
||||
case 0x0004:
|
||||
return "RST";
|
||||
case 0x0008:
|
||||
return "WDOG";
|
||||
default:
|
||||
return "unknown reset";
|
||||
}
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
u32 srev = get_cpu_rev();
|
||||
|
||||
printf("CPU: Freescale i.MX35 rev %d.%d at %d MHz.\n",
|
||||
(srev & 0xF0) >> 4, (srev & 0x0F),
|
||||
get_mcu_main_clk() / 1000000);
|
||||
|
||||
printf("Reset cause: %s\n", get_reset_cause());
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initializes on-chip ethernet controllers.
|
||||
* to override, implement board_eth_init()
|
||||
*/
|
||||
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
int rc = -ENODEV;
|
||||
|
||||
#if defined(CONFIG_FEC_MXC)
|
||||
rc = fecmxc_initialize(bis);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int get_clocks(void)
|
||||
{
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
|
||||
writew(4, &wdog->wcr);
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/mx35_pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
|
||||
/*
|
||||
* IOMUX register (base) addresses
|
||||
*/
|
||||
enum iomux_reg_addr {
|
||||
IOMUXGPR = IOMUXC_BASE_ADDR, /* General purpose */
|
||||
IOMUXSW_MUX_CTL = IOMUXC_BASE_ADDR + 4, /* MUX control */
|
||||
IOMUXSW_MUX_END = IOMUXC_BASE_ADDR + 0x324, /* last MUX control */
|
||||
IOMUXSW_PAD_CTL = IOMUXC_BASE_ADDR + 0x328, /* Pad control */
|
||||
IOMUXSW_PAD_END = IOMUXC_BASE_ADDR + 0x794, /* last Pad control */
|
||||
IOMUXSW_INPUT_CTL = IOMUXC_BASE_ADDR + 0x7AC, /* input select */
|
||||
IOMUXSW_INPUT_END = IOMUXC_BASE_ADDR + 0x9F4, /* last input select */
|
||||
};
|
||||
|
||||
#define MUX_PIN_NUM_MAX \
|
||||
(((IOMUXSW_PAD_END - IOMUXSW_PAD_CTL) >> 2) + 1)
|
||||
#define MUX_INPUT_NUM_MUX \
|
||||
(((IOMUXSW_INPUT_END - IOMUXSW_INPUT_CTL) >> 2) + 1)
|
||||
|
||||
#define PIN_TO_IOMUX_INDEX(pin) ((PIN_TO_IOMUX_PAD(pin) - 0x328) >> 2)
|
||||
|
||||
/*
|
||||
* Request ownership for an IO pin. This function has to be the first one
|
||||
* being called before that pin is used.
|
||||
*/
|
||||
void mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
u32 mux_reg = PIN_TO_IOMUX_MUX(pin);
|
||||
|
||||
if (mux_reg != NON_MUX_I) {
|
||||
mux_reg += IOMUXGPR;
|
||||
writel(cfg, mux_reg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Release ownership for an IO pin
|
||||
*/
|
||||
void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This function configures the pad value for a IOMUX pin.
|
||||
*
|
||||
* @param pin a pin number as defined in iomux_pin_name_t
|
||||
* @param config the ORed value of elements defined in iomux_pad_config_t
|
||||
*/
|
||||
void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
|
||||
{
|
||||
u32 pad_reg = IOMUXGPR + PIN_TO_IOMUX_PAD(pin);
|
||||
|
||||
writel(config, pad_reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function enables/disables the general purpose function for a particular
|
||||
* signal.
|
||||
*
|
||||
* @param gp one signal as defined in iomux_gp_func_t
|
||||
* @param en enable/disable
|
||||
*/
|
||||
void mxc_iomux_set_gpr(iomux_gp_func_t gp, int en)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
l = readl(IOMUXGPR);
|
||||
if (en)
|
||||
l |= gp;
|
||||
else
|
||||
l &= ~gp;
|
||||
|
||||
writel(l, IOMUXGPR);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function configures input path.
|
||||
*
|
||||
* @param input index of input select register as defined in
|
||||
* iomux_input_select_t
|
||||
* @param config the binary value of elements defined in
|
||||
* iomux_input_config_t
|
||||
*/
|
||||
void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
|
||||
{
|
||||
u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
|
||||
|
||||
writel(config, reg);
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* (C) Copyright 2007
|
||||
* Sascha Hauer, Pengutronix
|
||||
*
|
||||
* (C) Copyright 2008-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <div64.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define timestamp (gd->tbl)
|
||||
#define lastinc (gd->lastinc)
|
||||
|
||||
/* General purpose timers bitfields */
|
||||
#define GPTCR_SWR (1<<15) /* Software reset */
|
||||
#define GPTCR_FRR (1<<9) /* Freerun / restart */
|
||||
#define GPTCR_CLKSOURCE_32 (0x100<<6) /* Clock source */
|
||||
#define GPTCR_CLKSOURCE_IPG (0x001<<6) /* Clock source */
|
||||
#define GPTCR_TEN (1) /* Timer enable */
|
||||
|
||||
#define TIMER_FREQ_HZ mxc_get_clock(MXC_IPG_CLK)
|
||||
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
tick *= CONFIG_SYS_HZ;
|
||||
do_div(tick, TIMER_FREQ_HZ);
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long us_to_tick(unsigned long long usec)
|
||||
{
|
||||
usec *= TIMER_FREQ_HZ;
|
||||
do_div(usec, 1000000);
|
||||
|
||||
return usec;
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
int i;
|
||||
struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
|
||||
|
||||
/* setup GP Timer 1 */
|
||||
writel(GPTCR_SWR, &gpt->ctrl);
|
||||
for (i = 0; i < 100; i++)
|
||||
writel(0, &gpt->ctrl); /* We have no udelay by now */
|
||||
|
||||
writel(0, &gpt->pre);
|
||||
/* Freerun Mode, PERCLK1 input */
|
||||
writel(readl(&gpt->ctrl) |
|
||||
GPTCR_CLKSOURCE_IPG | GPTCR_TEN,
|
||||
&gpt->ctrl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR;
|
||||
ulong now = readl(&gpt->counter); /* current tick value */
|
||||
|
||||
if (now >= lastinc) {
|
||||
/*
|
||||
* normal mode (non roll)
|
||||
* move stamp forward with absolut diff ticks
|
||||
*/
|
||||
timestamp += (now - lastinc);
|
||||
} else {
|
||||
/* we have rollover of incrementer */
|
||||
timestamp += (0xFFFFFFFF - lastinc) + now;
|
||||
}
|
||||
lastinc = now;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
/*
|
||||
* get_ticks() returns a long long (64 bit), it wraps in
|
||||
* 2^64 / CONFIG_MX25_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
|
||||
* 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
|
||||
* 5 * 10^6 days - long enough.
|
||||
*/
|
||||
return tick_to_time(get_ticks());
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
/* delay x useconds AND preserve advance timstamp value */
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
unsigned long long tmp;
|
||||
ulong tmo;
|
||||
|
||||
tmo = us_to_tick(usec);
|
||||
tmp = get_ticks() + tmo; /* get current timestamp */
|
||||
|
||||
while (get_ticks() < tmp) /* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return TIMER_FREQ_HZ;
|
||||
}
|
||||
|
|
@ -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$(SOC).o
|
||||
|
||||
SOBJS = reset.o
|
||||
|
||||
COBJS = timer.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* armboot - Startup Code for OMP2420/ARM1136 CPU-core
|
||||
*
|
||||
* Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
|
||||
*
|
||||
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
|
||||
* Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
|
||||
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Copyright (c) 2003 Kshitij <kshitij@ti.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 <asm/arch/omap2420.h>
|
||||
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
ldr r1, rstctl /* get addr for global reset reg */
|
||||
mov r3, #0x2 /* full reset pll+mpu */
|
||||
str r3, [r1] /* force reset */
|
||||
mov r0, r0
|
||||
_loop_forever:
|
||||
b _loop_forever
|
||||
rstctl:
|
||||
.word PM_RSTCTRL_WKUP
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* (C) Copyright 2004
|
||||
* Texas Instruments
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
* Alex Zuepke <azu@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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/arch/bits.h>
|
||||
#include <asm/arch/omap2420.h>
|
||||
|
||||
#define TIMER_LOAD_VAL 0
|
||||
|
||||
/* macro to read the 32 bit timer */
|
||||
#define READ_TIMER (*((volatile ulong *)(CONFIG_SYS_TIMERBASE+TCRR)))
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int timer_init (void)
|
||||
{
|
||||
int32_t val;
|
||||
|
||||
/* Start the counter ticking up */
|
||||
*((int32_t *) (CONFIG_SYS_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/
|
||||
val = (CONFIG_SYS_PTV << 2) | BIT5 | BIT1 | BIT0; /* mask to enable timer*/
|
||||
*((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val; /* start timer */
|
||||
|
||||
/* reset time */
|
||||
gd->lastinc = READ_TIMER; /* capture current incrementer value */
|
||||
gd->tbl = 0; /* start "advancing" time stamp */
|
||||
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
ulong get_timer (ulong base)
|
||||
{
|
||||
return get_timer_masked () - base;
|
||||
}
|
||||
|
||||
/* delay x useconds AND preserve advance timestamp value */
|
||||
void __udelay (unsigned long usec)
|
||||
{
|
||||
ulong tmo, tmp;
|
||||
|
||||
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
|
||||
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
|
||||
tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
} else { /* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
|
||||
tmp = get_timer (0); /* get current timestamp */
|
||||
if ((tmo + tmp + 1) < tmp) { /* if setting this forward will roll */
|
||||
/* time stamp, then reset time */
|
||||
gd->lastinc = READ_TIMER; /* capture incrementer value */
|
||||
gd->tbl = 0; /* start time stamp */
|
||||
} else {
|
||||
tmo += tmp; /* else, set advancing stamp wake up time */
|
||||
}
|
||||
while (get_timer_masked () < tmo)/* loop till event */
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
ulong get_timer_masked (void)
|
||||
{
|
||||
ulong now = READ_TIMER; /* current tick value */
|
||||
|
||||
if (now >= gd->lastinc) /* normal mode (non roll) */
|
||||
gd->tbl += (now - gd->lastinc); /* move stamp fordward with absoulte diff ticks */
|
||||
else /* we have rollover of incrementer */
|
||||
gd->tbl += (0xFFFFFFFF - gd->lastinc) + now;
|
||||
gd->lastinc = now;
|
||||
return gd->tbl;
|
||||
}
|
||||
|
||||
/* waits specified delay value and resets timestamp */
|
||||
void udelay_masked (unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
ulong endtime;
|
||||
signed long diff;
|
||||
|
||||
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
|
||||
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
|
||||
tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
|
||||
tmo /= 1000; /* finish normalize. */
|
||||
} else { /* else small number, don't kill it prior to HZ multiply */
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
endtime = get_timer_masked () + tmo;
|
||||
|
||||
do {
|
||||
ulong now = get_timer_masked ();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
ulong tbclk;
|
||||
tbclk = CONFIG_SYS_HZ;
|
||||
return tbclk;
|
||||
}
|
||||
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
* armboot - Startup Code for OMP2420/ARM1136 CPU-core
|
||||
*
|
||||
* Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
|
||||
*
|
||||
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
|
||||
* Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
|
||||
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Copyright (c) 2003 Kshitij <kshitij@ti.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 <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
.globl _start
|
||||
_start: b reset
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
ldr pc, _hang
|
||||
ldr pc, _hang
|
||||
ldr pc, _hang
|
||||
ldr pc, _hang
|
||||
ldr pc, _hang
|
||||
ldr pc, _hang
|
||||
ldr pc, _hang
|
||||
|
||||
_hang:
|
||||
.word do_hang
|
||||
.word 0x12345678
|
||||
.word 0x12345678
|
||||
.word 0x12345678
|
||||
.word 0x12345678
|
||||
.word 0x12345678
|
||||
.word 0x12345678
|
||||
.word 0x12345678 /* now 16*4=64 */
|
||||
#else
|
||||
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 */
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
.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
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.globl _TEXT_BASE
|
||||
_TEXT_BASE:
|
||||
.word CONFIG_SYS_TEXT_BASE
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
* Subtracting _start from them lets the linker put their
|
||||
* relative position in the executable instead of leaving
|
||||
* them null.
|
||||
*/
|
||||
.globl _bss_start_ofs
|
||||
_bss_start_ofs:
|
||||
.word __bss_start - _start
|
||||
|
||||
.globl _bss_end_ofs
|
||||
_bss_end_ofs:
|
||||
.word __bss_end__ - _start
|
||||
|
||||
.globl _end_ofs
|
||||
_end_ofs:
|
||||
.word _end - _start
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
||||
.globl IRQ_STACK_START_IN
|
||||
IRQ_STACK_START_IN:
|
||||
.word 0x0badc0de
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0,cpsr
|
||||
bic r0,r0,#0x1f
|
||||
orr r0,r0,#0xd3
|
||||
msr cpsr,r0
|
||||
|
||||
#ifdef CONFIG_OMAP2420H4
|
||||
/* Copy vectors to mask ROM indirect addr */
|
||||
adr r0, _start /* r0 <- current position of code */
|
||||
add r0, r0, #4 /* skip reset vector */
|
||||
mov r2, #64 /* r2 <- size to copy */
|
||||
add r2, r0, r2 /* r2 <- source end address */
|
||||
mov r1, #SRAM_OFFSET0 /* build vect addr */
|
||||
mov r3, #SRAM_OFFSET1
|
||||
add r1, r1, r3
|
||||
mov r3, #SRAM_OFFSET2
|
||||
add r1, r1, r3
|
||||
next:
|
||||
ldmia r0!, {r3-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r3-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
bne next /* loop until equal */
|
||||
bl cpy_clk_code /* put dpll adjust code behind vectors */
|
||||
#endif
|
||||
/* the mask ROM code should have PLL and others stable */
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
bl cpu_init_crit
|
||||
#endif
|
||||
|
||||
/* Set stackpointer in internal RAM to call board_init_f */
|
||||
call_board_init_f:
|
||||
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
|
||||
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
|
||||
ldr r0,=0x00000000
|
||||
|
||||
bl board_init_f
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* void relocate_code (addr_sp, gd, addr_moni)
|
||||
*
|
||||
* This "function" does not return, instead it continues in RAM
|
||||
* after relocating the monitor code.
|
||||
*
|
||||
*/
|
||||
.globl relocate_code
|
||||
relocate_code:
|
||||
mov r4, r0 /* save addr_sp */
|
||||
mov r5, r1 /* save addr of gd */
|
||||
mov r6, r2 /* save addr of destination */
|
||||
|
||||
/* Set up the stack */
|
||||
stack_setup:
|
||||
mov sp, r4
|
||||
|
||||
adr r0, _start
|
||||
cmp r0, r6
|
||||
beq clear_bss /* skip relocation */
|
||||
mov r1, r6 /* r1 <- scratch for copy_loop */
|
||||
ldr r3, _bss_start_ofs
|
||||
add r2, r0, r3 /* r2 <- source end address */
|
||||
|
||||
copy_loop:
|
||||
ldmia r0!, {r9-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r9-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
blo copy_loop
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* fix .rel.dyn relocations
|
||||
*/
|
||||
ldr r0, _TEXT_BASE /* r0 <- Text base */
|
||||
sub r9, r6, r0 /* r9 <- relocation offset */
|
||||
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
|
||||
add r10, r10, r0 /* r10 <- sym table in FLASH */
|
||||
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
|
||||
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
|
||||
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
|
||||
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
|
||||
fixloop:
|
||||
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
|
||||
add r0, r0, r9 /* r0 <- location to fix up in RAM */
|
||||
ldr r1, [r2, #4]
|
||||
and r7, r1, #0xff
|
||||
cmp r7, #23 /* relative fixup? */
|
||||
beq fixrel
|
||||
cmp r7, #2 /* absolute fixup? */
|
||||
beq fixabs
|
||||
/* ignore unknown type of fixup */
|
||||
b fixnext
|
||||
fixabs:
|
||||
/* absolute fix: set location to (offset) symbol value */
|
||||
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
|
||||
add r1, r10, r1 /* r1 <- address of symbol in table */
|
||||
ldr r1, [r1, #4] /* r1 <- symbol value */
|
||||
add r1, r1, r9 /* r1 <- relocated sym addr */
|
||||
b fixnext
|
||||
fixrel:
|
||||
/* relative fix: increase location by offset */
|
||||
ldr r1, [r0]
|
||||
add r1, r1, r9
|
||||
fixnext:
|
||||
str r1, [r0]
|
||||
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
|
||||
cmp r2, r3
|
||||
blo fixloop
|
||||
#endif
|
||||
|
||||
clear_bss:
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
ldr r0, _bss_start_ofs
|
||||
ldr r1, _bss_end_ofs
|
||||
mov r4, r6 /* reloc addr */
|
||||
add r0, r0, r4
|
||||
add r1, r1, r4
|
||||
mov r2, #0x00000000 /* clear */
|
||||
|
||||
clbss_l:cmp r0, r1 /* clear loop... */
|
||||
bhs clbss_e /* if reached end of bss, exit */
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
b clbss_l
|
||||
clbss_e:
|
||||
#endif /* #ifndef CONFIG_SPL_BUILD */
|
||||
|
||||
/*
|
||||
* We are done. Do not return, instead branch to second part of board
|
||||
* initialization, now running from RAM.
|
||||
*/
|
||||
#ifdef CONFIG_NAND_SPL
|
||||
ldr r0, _nand_boot_ofs
|
||||
mov pc, r0
|
||||
|
||||
_nand_boot_ofs:
|
||||
.word nand_boot
|
||||
#else
|
||||
jump_2_ram:
|
||||
ldr r0, _board_init_r_ofs
|
||||
ldr r1, _TEXT_BASE
|
||||
add lr, r0, r1
|
||||
add lr, lr, r9
|
||||
/* setup parameters for board_init_r */
|
||||
mov r0, r5 /* gd_t */
|
||||
mov r1, r6 /* dest_addr */
|
||||
/* jump to it ... */
|
||||
mov pc, lr
|
||||
|
||||
_board_init_r_ofs:
|
||||
.word board_init_r - _start
|
||||
#endif
|
||||
|
||||
_rel_dyn_start_ofs:
|
||||
.word __rel_dyn_start - _start
|
||||
_rel_dyn_end_ofs:
|
||||
.word __rel_dyn_end - _start
|
||||
_dynsym_start_ofs:
|
||||
.word __dynsym_start - _start
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* CPU_init_critical registers
|
||||
*
|
||||
* setup important registers
|
||||
* setup memory timing
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
cpu_init_crit:
|
||||
/*
|
||||
* flush v4 I/D caches
|
||||
*/
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */
|
||||
mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified 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
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*
|
||||
* Jump to board specific initialization... The Mask ROM will have already initialized
|
||||
* basic memory. Go here to bump up clock rate and handle wake up conditions.
|
||||
*/
|
||||
mov ip, lr /* persevere link reg across call */
|
||||
bl lowlevel_init /* go setup pll,mux,memory */
|
||||
mov lr, ip /* restore link */
|
||||
mov pc, lr /* back to my caller */
|
||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* 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 ...
|
||||
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
|
||||
*/
|
||||
|
||||
.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, IRQ_STACK_START_IN @ 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 irq_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
|
||||
stmdb r8, {sp, lr}^ @ Calling SP, LR
|
||||
str lr, [r8, #0] @ Save calling PC
|
||||
mrs r6, spsr
|
||||
str r6, [r8, #4] @ Save CPSR
|
||||
str r0, [r8, #8] @ Save OLD_R0
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_restore_user_regs
|
||||
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
|
||||
mov r0, r0
|
||||
ldr lr, [sp, #S_PC] @ Get PC
|
||||
add sp, sp, #S_FRAME_SIZE
|
||||
subs pc, lr, #4 @ return & move spsr_svc into cpsr
|
||||
.endm
|
||||
|
||||
.macro get_bad_stack
|
||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode)
|
||||
|
||||
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, IRQ_STACK_START_IN @ get data regions start
|
||||
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
|
||||
|
||||
.macro get_irq_stack @ setup IRQ stack
|
||||
ldr sp, IRQ_STACK_START
|
||||
.endm
|
||||
|
||||
.macro get_fiq_stack @ setup FIQ stack
|
||||
ldr sp, FIQ_STACK_START
|
||||
.endm
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
||||
/*
|
||||
* exception handlers
|
||||
*/
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
.align 5
|
||||
do_hang:
|
||||
ldr sp, _TEXT_BASE /* use 32 words about stack */
|
||||
bl hang /* hang and never return */
|
||||
#else /* !CONFIG_SPL_BUILD */
|
||||
.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
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_irq_stack
|
||||
irq_save_user_regs
|
||||
bl do_irq
|
||||
irq_restore_user_regs
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_fiq_stack
|
||||
/* someone ought to write a more effiction fiq_save_user_regs */
|
||||
irq_save_user_regs
|
||||
bl do_fiq
|
||||
irq_restore_user_regs
|
||||
|
||||
#else
|
||||
|
||||
.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
|
||||
.align 5
|
||||
.global arm1136_cache_flush
|
||||
arm1136_cache_flush:
|
||||
#if !defined(CONFIG_SYS_ICACHE_OFF)
|
||||
mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
|
||||
#endif
|
||||
#if !defined(CONFIG_SYS_DCACHE_OFF)
|
||||
mcr p15, 0, r1, c7, c14, 0 @ invalidate D cache
|
||||
#endif
|
||||
mov pc, lr @ back to caller
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (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).o
|
||||
|
||||
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)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@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-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
|
||||
#
|
||||
# =========================================================================
|
||||
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,\
|
||||
$(call cc-option,-malignment-traps,))
|
||||
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* (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, <garyj@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 <asm/system.h>
|
||||
|
||||
static void cache_flush (void);
|
||||
|
||||
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();
|
||||
/* flush I/D-cache */
|
||||
cache_flush();
|
||||
|
||||
return 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));
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (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).o
|
||||
|
||||
SOBJS = reset.o
|
||||
|
||||
COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o
|
||||
COBJS-y += timer.o
|
||||
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@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-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
|
||||
#
|
||||
# =========================================================================
|
||||
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,\
|
||||
$(call cc-option,-malignment-traps,))
|
||||
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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 <asm/arch/s3c6400.h>
|
||||
|
||||
.globl mem_ctrl_asm_init
|
||||
mem_ctrl_asm_init:
|
||||
/* 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
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Samsung Electronics.
|
||||
* Minkyu Kang <mk7.kang@samsung.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 <asm/arch/s3c6400.h>
|
||||
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
ldr r1, =ELFIN_CLOCK_POWER_BASE
|
||||
ldr r2, [r1, #SYS_ID_OFFSET]
|
||||
ldr r3, =0xffff
|
||||
and r2, r3, r2, lsr #12
|
||||
str r2, [r1, #SW_RST_OFFSET]
|
||||
_loop_forever:
|
||||
b _loop_forever
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* (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 <asm/arch/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;
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* (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, <garyj@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 <asm/arch/s3c6400.h>
|
||||
#include <div64.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 timer_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);
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
unsigned long long res = get_ticks();
|
||||
do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ)));
|
||||
return res;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
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*/;
|
||||
}
|
||||
|
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
* armboot - Startup Code for 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 <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
#ifdef CONFIG_ENABLE_MMU
|
||||
#include <asm/proc/domain.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
|
||||
#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_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
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.globl _TEXT_BASE
|
||||
_TEXT_BASE:
|
||||
.word CONFIG_SYS_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 CONFIG_SYS_PHY_UBOOT_BASE
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
* Subtracting _start from them lets the linker put their
|
||||
* relative position in the executable instead of leaving
|
||||
* them null.
|
||||
*/
|
||||
|
||||
.globl _bss_start_ofs
|
||||
_bss_start_ofs:
|
||||
.word __bss_start - _start
|
||||
|
||||
.globl _bss_end_ofs
|
||||
_bss_end_ofs:
|
||||
.word __bss_end__ - _start
|
||||
|
||||
.globl _end_ofs
|
||||
_end_ofs:
|
||||
.word _end - _start
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
||||
.globl IRQ_STACK_START_IN
|
||||
IRQ_STACK_START_IN:
|
||||
.word 0x0badc0de
|
||||
|
||||
/*
|
||||
* 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 r2, mmu_disable_phys
|
||||
sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - CONFIG_SYS_TEXT_BASE)
|
||||
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
|
||||
mmu_disable_phys:
|
||||
|
||||
#ifdef CONFIG_DISABLE_TCM
|
||||
/*
|
||||
* Disable the TCMs
|
||||
*/
|
||||
mrc p15, 0, r0, c0, c0, 2 /* Return TCM details */
|
||||
cmp r0, #0
|
||||
beq skip_tcmdisable
|
||||
mov r1, #0
|
||||
mov r2, #1
|
||||
tst r0, r2
|
||||
mcrne p15, 0, r1, c9, c1, 1 /* Disable Instruction TCM if present*/
|
||||
tst r0, r2, LSL #16
|
||||
mcrne p15, 0, r1, c9, c1, 0 /* Disable Data TCM if present*/
|
||||
skip_tcmdisable:
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PERIPORT_REMAP
|
||||
/* Peri port setup */
|
||||
ldr r0, =CONFIG_PERIPORT_BASE
|
||||
orr r0, r0, #CONFIG_PERIPORT_SIZE
|
||||
mcr p15,0,r0,c15,c2,4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Go setup Memory and board specific bits prior to relocation.
|
||||
*/
|
||||
bl lowlevel_init /* go setup pll,mux,memory */
|
||||
|
||||
/* Set stackpointer in internal RAM to call board_init_f */
|
||||
call_board_init_f:
|
||||
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
|
||||
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
|
||||
ldr r0,=0x00000000
|
||||
bl board_init_f
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* void relocate_code (addr_sp, gd, addr_moni)
|
||||
*
|
||||
* This "function" does not return, instead it continues in RAM
|
||||
* after relocating the monitor code.
|
||||
*
|
||||
*/
|
||||
.globl relocate_code
|
||||
relocate_code:
|
||||
mov r4, r0 /* save addr_sp */
|
||||
mov r5, r1 /* save addr of gd */
|
||||
mov r6, r2 /* save addr of destination */
|
||||
|
||||
/* Set up the stack */
|
||||
stack_setup:
|
||||
mov sp, r4
|
||||
|
||||
adr r0, _start
|
||||
cmp r0, r6
|
||||
beq clear_bss /* skip relocation */
|
||||
mov r1, r6 /* r1 <- scratch for copy_loop */
|
||||
ldr r3, _bss_start_ofs
|
||||
add r2, r0, r3 /* r2 <- source end address */
|
||||
|
||||
copy_loop:
|
||||
ldmia r0!, {r9-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r9-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
blo copy_loop
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* fix .rel.dyn relocations
|
||||
*/
|
||||
ldr r0, _TEXT_BASE /* r0 <- Text base */
|
||||
sub r9, r6, r0 /* r9 <- relocation offset */
|
||||
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
|
||||
add r10, r10, r0 /* r10 <- sym table in FLASH */
|
||||
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
|
||||
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
|
||||
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
|
||||
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
|
||||
fixloop:
|
||||
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
|
||||
add r0, r0, r9 /* r0 <- location to fix up in RAM */
|
||||
ldr r1, [r2, #4]
|
||||
and r7, r1, #0xff
|
||||
cmp r7, #23 /* relative fixup? */
|
||||
beq fixrel
|
||||
cmp r7, #2 /* absolute fixup? */
|
||||
beq fixabs
|
||||
/* ignore unknown type of fixup */
|
||||
b fixnext
|
||||
fixabs:
|
||||
/* absolute fix: set location to (offset) symbol value */
|
||||
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
|
||||
add r1, r10, r1 /* r1 <- address of symbol in table */
|
||||
ldr r1, [r1, #4] /* r1 <- symbol value */
|
||||
add r1, r1, r9 /* r1 <- relocated sym addr */
|
||||
b fixnext
|
||||
fixrel:
|
||||
/* relative fix: increase location by offset */
|
||||
ldr r1, [r0]
|
||||
add r1, r1, r9
|
||||
fixnext:
|
||||
str r1, [r0]
|
||||
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
|
||||
cmp r2, r3
|
||||
blo fixloop
|
||||
#endif
|
||||
|
||||
#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, =CONFIG_SYS_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
|
||||
skip_hw_init:
|
||||
#endif
|
||||
|
||||
clear_bss:
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
ldr r0, _bss_start_ofs
|
||||
ldr r1, _bss_end_ofs
|
||||
mov r4, r6 /* reloc addr */
|
||||
add r0, r0, r4
|
||||
add r1, r1, r4
|
||||
mov r2, #0x00000000 /* clear */
|
||||
|
||||
clbss_l:cmp r0, r1 /* clear loop... */
|
||||
bhs clbss_e /* if reached end of bss, exit */
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
b clbss_l
|
||||
clbss_e:
|
||||
#ifndef CONFIG_NAND_SPL
|
||||
bl coloured_LED_init
|
||||
bl red_led_on
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are done. Do not return, instead branch to second part of board
|
||||
* initialization, now running from RAM.
|
||||
*/
|
||||
#ifdef CONFIG_NAND_SPL
|
||||
ldr pc, _nand_boot
|
||||
|
||||
_nand_boot: .word nand_boot
|
||||
#else
|
||||
ldr r0, _board_init_r_ofs
|
||||
adr r1, _start
|
||||
add lr, r0, r1
|
||||
add lr, lr, r9
|
||||
/* setup parameters for board_init_r */
|
||||
mov r0, r5 /* gd_t */
|
||||
mov r1, r6 /* dest_addr */
|
||||
/* jump to it ... */
|
||||
mov pc, lr
|
||||
|
||||
_board_init_r_ofs:
|
||||
.word board_init_r - _start
|
||||
#endif
|
||||
|
||||
_rel_dyn_start_ofs:
|
||||
.word __rel_dyn_start - _start
|
||||
_rel_dyn_end_ofs:
|
||||
.word __rel_dyn_end - _start
|
||||
_dynsym_start_ofs:
|
||||
.word __dynsym_start - _start
|
||||
|
||||
#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, IRQ_STACK_START_IN
|
||||
/* 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
|
||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
||||
|
||||
/* 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]
|
||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
||||
/* 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 */
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
COBJS += aemif.o clock.o init.o mux.o timer.o wdt.o
|
||||
SOBJS += lowlevel_init.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
|
||||
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* TNETV107X: Asynchronous EMIF Configuration
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
#define ASYNC_EMIF_BASE TNETV107X_ASYNC_EMIF_CNTRL_BASE
|
||||
#define ASYNC_EMIF_CONFIG(cs) (ASYNC_EMIF_BASE+0x10+(cs)*4)
|
||||
#define ASYNC_EMIF_ONENAND_CONTROL (ASYNC_EMIF_BASE+0x5c)
|
||||
#define ASYNC_EMIF_NAND_CONTROL (ASYNC_EMIF_BASE+0x60)
|
||||
#define ASYNC_EMIF_WAITCYCLE_CONFIG (ASYNC_EMIF_BASE+0x4)
|
||||
|
||||
#define CONFIG_SELECT_STROBE(v) ((v) ? 1 << 31 : 0)
|
||||
#define CONFIG_EXTEND_WAIT(v) ((v) ? 1 << 30 : 0)
|
||||
#define CONFIG_WR_SETUP(v) (((v) & 0x0f) << 26)
|
||||
#define CONFIG_WR_STROBE(v) (((v) & 0x3f) << 20)
|
||||
#define CONFIG_WR_HOLD(v) (((v) & 0x07) << 17)
|
||||
#define CONFIG_RD_SETUP(v) (((v) & 0x0f) << 13)
|
||||
#define CONFIG_RD_STROBE(v) (((v) & 0x3f) << 7)
|
||||
#define CONFIG_RD_HOLD(v) (((v) & 0x07) << 4)
|
||||
#define CONFIG_TURN_AROUND(v) (((v) & 0x03) << 2)
|
||||
#define CONFIG_WIDTH(v) (((v) & 0x03) << 0)
|
||||
|
||||
#define NUM_CS 4
|
||||
|
||||
#define set_config_field(reg, field, val) \
|
||||
do { \
|
||||
if (val != -1) { \
|
||||
reg &= ~CONFIG_##field(0xffffffff); \
|
||||
reg |= CONFIG_##field(val); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void configure_async_emif(int cs, struct async_emif_config *cfg)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
if (cfg->mode == ASYNC_EMIF_MODE_NAND) {
|
||||
tmp = __raw_readl(ASYNC_EMIF_NAND_CONTROL);
|
||||
tmp |= (1 << cs);
|
||||
__raw_writel(tmp, ASYNC_EMIF_NAND_CONTROL);
|
||||
|
||||
} else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) {
|
||||
tmp = __raw_readl(ASYNC_EMIF_ONENAND_CONTROL);
|
||||
tmp |= (1 << cs);
|
||||
__raw_writel(tmp, ASYNC_EMIF_ONENAND_CONTROL);
|
||||
}
|
||||
|
||||
tmp = __raw_readl(ASYNC_EMIF_CONFIG(cs));
|
||||
|
||||
set_config_field(tmp, SELECT_STROBE, cfg->select_strobe);
|
||||
set_config_field(tmp, EXTEND_WAIT, cfg->extend_wait);
|
||||
set_config_field(tmp, WR_SETUP, cfg->wr_setup);
|
||||
set_config_field(tmp, WR_STROBE, cfg->wr_strobe);
|
||||
set_config_field(tmp, WR_HOLD, cfg->wr_hold);
|
||||
set_config_field(tmp, RD_SETUP, cfg->rd_setup);
|
||||
set_config_field(tmp, RD_STROBE, cfg->rd_strobe);
|
||||
set_config_field(tmp, RD_HOLD, cfg->rd_hold);
|
||||
set_config_field(tmp, TURN_AROUND, cfg->turn_around);
|
||||
set_config_field(tmp, WIDTH, cfg->width);
|
||||
|
||||
__raw_writel(tmp, ASYNC_EMIF_CONFIG(cs));
|
||||
}
|
||||
|
||||
void init_async_emif(int num_cs, struct async_emif_config *config)
|
||||
{
|
||||
int cs;
|
||||
|
||||
clk_enable(TNETV107X_LPSC_AEMIF);
|
||||
|
||||
for (cs = 0; cs < num_cs; cs++)
|
||||
configure_async_emif(cs, config + cs);
|
||||
}
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* TNETV107X: Clock management APIs
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
#define CLOCK_BASE TNETV107X_CLOCK_CONTROL_BASE
|
||||
#define PSC_BASE TNETV107X_PSC_BASE
|
||||
|
||||
#define BIT(x) (1 << (x))
|
||||
|
||||
#define MAX_PREDIV 64
|
||||
#define MAX_POSTDIV 8
|
||||
#define MAX_MULT 512
|
||||
#define MAX_DIV (MAX_PREDIV * MAX_POSTDIV)
|
||||
|
||||
/* LPSC registers */
|
||||
#define PSC_PTCMD 0x120
|
||||
#define PSC_PTSTAT 0x128
|
||||
#define PSC_MDSTAT(n) (0x800 + (n) * 4)
|
||||
#define PSC_MDCTL(n) (0xA00 + (n) * 4)
|
||||
|
||||
#define PSC_MDCTL_LRSTZ BIT(8)
|
||||
|
||||
#define psc_reg_read(reg) __raw_readl((u32 *)(PSC_BASE + (reg)))
|
||||
#define psc_reg_write(reg, val) __raw_writel(val, (u32 *)(PSC_BASE + (reg)))
|
||||
|
||||
/* SSPLL registers */
|
||||
struct sspll_regs {
|
||||
u32 modes;
|
||||
u32 postdiv;
|
||||
u32 prediv;
|
||||
u32 mult_factor;
|
||||
u32 divider_range;
|
||||
u32 bw_divider;
|
||||
u32 spr_amount;
|
||||
u32 spr_rate_div;
|
||||
u32 diag;
|
||||
};
|
||||
|
||||
/* SSPLL base addresses */
|
||||
static struct sspll_regs *sspll_regs[] = {
|
||||
(struct sspll_regs *)(CLOCK_BASE + 0x040),
|
||||
(struct sspll_regs *)(CLOCK_BASE + 0x080),
|
||||
(struct sspll_regs *)(CLOCK_BASE + 0x0c0),
|
||||
};
|
||||
|
||||
#define sspll_reg(pll, reg) (&(sspll_regs[pll]->reg))
|
||||
#define sspll_reg_read(pll, reg) __raw_readl(sspll_reg(pll, reg))
|
||||
#define sspll_reg_write(pll, reg, val) __raw_writel(val, sspll_reg(pll, reg))
|
||||
|
||||
|
||||
/* PLL Control Registers */
|
||||
struct pllctl_regs {
|
||||
u32 ctl; /* 00 */
|
||||
u32 ocsel; /* 04 */
|
||||
u32 secctl; /* 08 */
|
||||
u32 __pad0;
|
||||
u32 mult; /* 10 */
|
||||
u32 prediv; /* 14 */
|
||||
u32 div1; /* 18 */
|
||||
u32 div2; /* 1c */
|
||||
u32 div3; /* 20 */
|
||||
u32 oscdiv1; /* 24 */
|
||||
u32 postdiv; /* 28 */
|
||||
u32 bpdiv; /* 2c */
|
||||
u32 wakeup; /* 30 */
|
||||
u32 __pad1;
|
||||
u32 cmd; /* 38 */
|
||||
u32 stat; /* 3c */
|
||||
u32 alnctl; /* 40 */
|
||||
u32 dchange; /* 44 */
|
||||
u32 cken; /* 48 */
|
||||
u32 ckstat; /* 4c */
|
||||
u32 systat; /* 50 */
|
||||
u32 ckctl; /* 54 */
|
||||
u32 __pad2[2];
|
||||
u32 div4; /* 60 */
|
||||
u32 div5; /* 64 */
|
||||
u32 div6; /* 68 */
|
||||
u32 div7; /* 6c */
|
||||
u32 div8; /* 70 */
|
||||
};
|
||||
|
||||
struct lpsc_map {
|
||||
int pll, div;
|
||||
};
|
||||
|
||||
static struct pllctl_regs *pllctl_regs[] = {
|
||||
(struct pllctl_regs *)(CLOCK_BASE + 0x700),
|
||||
(struct pllctl_regs *)(CLOCK_BASE + 0x300),
|
||||
(struct pllctl_regs *)(CLOCK_BASE + 0x500),
|
||||
};
|
||||
|
||||
#define pllctl_reg(pll, reg) (&(pllctl_regs[pll]->reg))
|
||||
#define pllctl_reg_read(pll, reg) __raw_readl(pllctl_reg(pll, reg))
|
||||
#define pllctl_reg_write(pll, reg, val) __raw_writel(val, pllctl_reg(pll, reg))
|
||||
|
||||
#define pllctl_reg_rmw(pll, reg, mask, val) \
|
||||
pllctl_reg_write(pll, reg, \
|
||||
(pllctl_reg_read(pll, reg) & ~(mask)) | val)
|
||||
|
||||
#define pllctl_reg_setbits(pll, reg, mask) \
|
||||
pllctl_reg_rmw(pll, reg, 0, mask)
|
||||
|
||||
#define pllctl_reg_clrbits(pll, reg, mask) \
|
||||
pllctl_reg_rmw(pll, reg, mask, 0)
|
||||
|
||||
/* PLLCTL Bits */
|
||||
#define PLLCTL_CLKMODE BIT(8)
|
||||
#define PLLCTL_PLLSELB BIT(7)
|
||||
#define PLLCTL_PLLENSRC BIT(5)
|
||||
#define PLLCTL_PLLDIS BIT(4)
|
||||
#define PLLCTL_PLLRST BIT(3)
|
||||
#define PLLCTL_PLLPWRDN BIT(1)
|
||||
#define PLLCTL_PLLEN BIT(0)
|
||||
|
||||
#define PLLDIV_ENABLE BIT(15)
|
||||
|
||||
static int pll_div_offset[] = {
|
||||
#define div_offset(reg) offsetof(struct pllctl_regs, reg)
|
||||
div_offset(div1), div_offset(div2), div_offset(div3),
|
||||
div_offset(div4), div_offset(div5), div_offset(div6),
|
||||
div_offset(div7), div_offset(div8),
|
||||
};
|
||||
|
||||
static unsigned long pll_bypass_mask[] = { 1, 4, 2 };
|
||||
static unsigned long pll_div_mask[] = { 0x01ff, 0x00ff, 0x00ff };
|
||||
|
||||
/* Mappings from PLL+DIV to subsystem clocks */
|
||||
#define sys_arm1176_clk {SYS_PLL, 0}
|
||||
#define sys_dsp_clk {SYS_PLL, 1}
|
||||
#define sys_ddr_clk {SYS_PLL, 2}
|
||||
#define sys_full_clk {SYS_PLL, 3}
|
||||
#define sys_lcd_clk {SYS_PLL, 4}
|
||||
#define sys_vlynq_ref_clk {SYS_PLL, 5}
|
||||
#define sys_tsc_clk {SYS_PLL, 6}
|
||||
#define sys_half_clk {SYS_PLL, 7}
|
||||
|
||||
#define eth_clk_5 {ETH_PLL, 0}
|
||||
#define eth_clk_50 {ETH_PLL, 1}
|
||||
#define eth_clk_125 {ETH_PLL, 2}
|
||||
#define eth_clk_250 {ETH_PLL, 3}
|
||||
#define eth_clk_25 {ETH_PLL, 4}
|
||||
|
||||
#define tdm_clk {TDM_PLL, 0}
|
||||
#define tdm_extra_clk {TDM_PLL, 1}
|
||||
#define tdm1_clk {TDM_PLL, 2}
|
||||
|
||||
/* Optimization barrier */
|
||||
#define barrier() \
|
||||
__asm__ __volatile__("mov r0, r0\n" : : : "memory");
|
||||
|
||||
static const struct lpsc_map lpsc_clk_map[] = {
|
||||
[TNETV107X_LPSC_ARM] = sys_arm1176_clk,
|
||||
[TNETV107X_LPSC_GEM] = sys_dsp_clk,
|
||||
[TNETV107X_LPSC_DDR2_PHY] = sys_ddr_clk,
|
||||
[TNETV107X_LPSC_TPCC] = sys_full_clk,
|
||||
[TNETV107X_LPSC_TPTC0] = sys_full_clk,
|
||||
[TNETV107X_LPSC_TPTC1] = sys_full_clk,
|
||||
[TNETV107X_LPSC_RAM] = sys_full_clk,
|
||||
[TNETV107X_LPSC_MBX_LITE] = sys_arm1176_clk,
|
||||
[TNETV107X_LPSC_LCD] = sys_lcd_clk,
|
||||
[TNETV107X_LPSC_ETHSS] = eth_clk_125,
|
||||
[TNETV107X_LPSC_AEMIF] = sys_full_clk,
|
||||
[TNETV107X_LPSC_CHIP_CFG] = sys_half_clk,
|
||||
[TNETV107X_LPSC_TSC] = sys_tsc_clk,
|
||||
[TNETV107X_LPSC_ROM] = sys_half_clk,
|
||||
[TNETV107X_LPSC_UART2] = sys_half_clk,
|
||||
[TNETV107X_LPSC_PKTSEC] = sys_half_clk,
|
||||
[TNETV107X_LPSC_SECCTL] = sys_half_clk,
|
||||
[TNETV107X_LPSC_KEYMGR] = sys_half_clk,
|
||||
[TNETV107X_LPSC_KEYPAD] = sys_half_clk,
|
||||
[TNETV107X_LPSC_GPIO] = sys_half_clk,
|
||||
[TNETV107X_LPSC_MDIO] = sys_half_clk,
|
||||
[TNETV107X_LPSC_SDIO0] = sys_half_clk,
|
||||
[TNETV107X_LPSC_UART0] = sys_half_clk,
|
||||
[TNETV107X_LPSC_UART1] = sys_half_clk,
|
||||
[TNETV107X_LPSC_TIMER0] = sys_half_clk,
|
||||
[TNETV107X_LPSC_TIMER1] = sys_half_clk,
|
||||
[TNETV107X_LPSC_WDT_ARM] = sys_half_clk,
|
||||
[TNETV107X_LPSC_WDT_DSP] = sys_half_clk,
|
||||
[TNETV107X_LPSC_SSP] = sys_half_clk,
|
||||
[TNETV107X_LPSC_TDM0] = tdm_clk,
|
||||
[TNETV107X_LPSC_VLYNQ] = sys_vlynq_ref_clk,
|
||||
[TNETV107X_LPSC_MCDMA] = sys_half_clk,
|
||||
[TNETV107X_LPSC_USB0] = sys_half_clk,
|
||||
[TNETV107X_LPSC_TDM1] = tdm1_clk,
|
||||
[TNETV107X_LPSC_DEBUGSS] = sys_half_clk,
|
||||
[TNETV107X_LPSC_ETHSS_RGMII] = eth_clk_250,
|
||||
[TNETV107X_LPSC_SYSTEM] = sys_half_clk,
|
||||
[TNETV107X_LPSC_IMCOP] = sys_dsp_clk,
|
||||
[TNETV107X_LPSC_SPARE] = sys_half_clk,
|
||||
[TNETV107X_LPSC_SDIO1] = sys_half_clk,
|
||||
[TNETV107X_LPSC_USB1] = sys_half_clk,
|
||||
[TNETV107X_LPSC_USBSS] = sys_half_clk,
|
||||
[TNETV107X_LPSC_DDR2_EMIF1_VRST] = sys_ddr_clk,
|
||||
[TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST] = sys_ddr_clk,
|
||||
};
|
||||
|
||||
static const unsigned long pll_ext_freq[] = {
|
||||
[SYS_PLL] = CONFIG_PLL_SYS_EXT_FREQ,
|
||||
[ETH_PLL] = CONFIG_PLL_ETH_EXT_FREQ,
|
||||
[TDM_PLL] = CONFIG_PLL_TDM_EXT_FREQ,
|
||||
};
|
||||
|
||||
static unsigned long pll_freq_get(int pll)
|
||||
{
|
||||
unsigned long mult = 1, prediv = 1, postdiv = 1;
|
||||
unsigned long ref = CONFIG_SYS_INT_OSC_FREQ;
|
||||
unsigned long ret;
|
||||
u32 bypass;
|
||||
|
||||
bypass = __raw_readl((u32 *)(CLOCK_BASE));
|
||||
if (!(bypass & pll_bypass_mask[pll])) {
|
||||
mult = sspll_reg_read(pll, mult_factor);
|
||||
prediv = sspll_reg_read(pll, prediv) + 1;
|
||||
postdiv = sspll_reg_read(pll, postdiv) + 1;
|
||||
}
|
||||
|
||||
if (pllctl_reg_read(pll, ctl) & PLLCTL_CLKMODE)
|
||||
ref = pll_ext_freq[pll];
|
||||
|
||||
if (!(pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN))
|
||||
return ref;
|
||||
|
||||
ret = (unsigned long)(ref + ((unsigned long long)ref * mult) / 256);
|
||||
ret /= (prediv * postdiv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long __pll_div_freq_get(int pll, unsigned int fpll,
|
||||
int div)
|
||||
{
|
||||
int divider = 1;
|
||||
unsigned long divreg;
|
||||
|
||||
divreg = __raw_readl((void *)pllctl_regs[pll] + pll_div_offset[div]);
|
||||
|
||||
if (divreg & PLLDIV_ENABLE)
|
||||
divider = (divreg & pll_div_mask[pll]) + 1;
|
||||
|
||||
return fpll / divider;
|
||||
}
|
||||
|
||||
static unsigned long pll_div_freq_get(int pll, int div)
|
||||
{
|
||||
unsigned int fpll = pll_freq_get(pll);
|
||||
|
||||
return __pll_div_freq_get(pll, fpll, div);
|
||||
}
|
||||
|
||||
static void __pll_div_freq_set(int pll, unsigned int fpll, int div,
|
||||
unsigned long hz)
|
||||
{
|
||||
int divider = (fpll / hz - 1);
|
||||
|
||||
divider &= pll_div_mask[pll];
|
||||
divider |= PLLDIV_ENABLE;
|
||||
|
||||
__raw_writel(divider, (void *)pllctl_regs[pll] + pll_div_offset[div]);
|
||||
pllctl_reg_setbits(pll, alnctl, (1 << div));
|
||||
pllctl_reg_setbits(pll, dchange, (1 << div));
|
||||
}
|
||||
|
||||
static unsigned long pll_div_freq_set(int pll, int div, unsigned long hz)
|
||||
{
|
||||
unsigned int fpll = pll_freq_get(pll);
|
||||
|
||||
__pll_div_freq_set(pll, fpll, div, hz);
|
||||
|
||||
pllctl_reg_write(pll, cmd, 1);
|
||||
|
||||
/* Wait until new divider takes effect */
|
||||
while (pllctl_reg_read(pll, stat) & 0x01);
|
||||
|
||||
return __pll_div_freq_get(pll, fpll, div);
|
||||
}
|
||||
|
||||
unsigned long clk_get_rate(unsigned int clk)
|
||||
{
|
||||
return pll_div_freq_get(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div);
|
||||
}
|
||||
|
||||
unsigned long clk_round_rate(unsigned int clk, unsigned long hz)
|
||||
{
|
||||
unsigned long fpll, divider, pll;
|
||||
|
||||
pll = lpsc_clk_map[clk].pll;
|
||||
fpll = pll_freq_get(pll);
|
||||
divider = (fpll / hz - 1);
|
||||
divider &= pll_div_mask[pll];
|
||||
|
||||
return fpll / (divider + 1);
|
||||
}
|
||||
|
||||
int clk_set_rate(unsigned int clk, unsigned long _hz)
|
||||
{
|
||||
unsigned long hz;
|
||||
|
||||
hz = clk_round_rate(clk, _hz);
|
||||
if (hz != _hz)
|
||||
return -EINVAL; /* Cannot set to target freq */
|
||||
|
||||
pll_div_freq_set(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div, hz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lpsc_control(int mod, unsigned long state, int lrstz)
|
||||
{
|
||||
u32 mdctl;
|
||||
|
||||
mdctl = psc_reg_read(PSC_MDCTL(mod));
|
||||
mdctl &= ~0x1f;
|
||||
mdctl |= state;
|
||||
|
||||
if (lrstz == 0)
|
||||
mdctl &= ~PSC_MDCTL_LRSTZ;
|
||||
else if (lrstz == 1)
|
||||
mdctl |= PSC_MDCTL_LRSTZ;
|
||||
|
||||
psc_reg_write(PSC_MDCTL(mod), mdctl);
|
||||
|
||||
psc_reg_write(PSC_PTCMD, 1);
|
||||
|
||||
/* wait for power domain transition to end */
|
||||
while (psc_reg_read(PSC_PTSTAT) & 1);
|
||||
|
||||
/* Wait for module state change */
|
||||
while ((psc_reg_read(PSC_MDSTAT(mod)) & 0x1f) != state);
|
||||
}
|
||||
|
||||
int lpsc_status(unsigned int id)
|
||||
{
|
||||
return psc_reg_read(PSC_MDSTAT(id)) & 0x1f;
|
||||
}
|
||||
|
||||
static void init_pll(const struct pll_init_data *data)
|
||||
{
|
||||
unsigned long fpll;
|
||||
unsigned long best_pre = 0, best_post = 0, best_mult = 0;
|
||||
unsigned long div, prediv, postdiv, mult;
|
||||
unsigned long delta, actual;
|
||||
long best_delta = -1;
|
||||
int i;
|
||||
u32 tmp;
|
||||
|
||||
if (data->pll == SYS_PLL)
|
||||
return; /* cannot reconfigure system pll on the fly */
|
||||
|
||||
tmp = pllctl_reg_read(data->pll, ctl);
|
||||
if (data->internal_osc) {
|
||||
tmp &= ~PLLCTL_CLKMODE;
|
||||
fpll = CONFIG_SYS_INT_OSC_FREQ;
|
||||
} else {
|
||||
tmp |= PLLCTL_CLKMODE;
|
||||
fpll = pll_ext_freq[data->pll];
|
||||
}
|
||||
pllctl_reg_write(data->pll, ctl, tmp);
|
||||
|
||||
mult = data->pll_freq / fpll;
|
||||
for (mult = MAX(mult, 1); mult <= MAX_MULT; mult++) {
|
||||
div = (fpll * mult) / data->pll_freq;
|
||||
if (div < 1 || div > MAX_DIV)
|
||||
continue;
|
||||
|
||||
for (postdiv = 1; postdiv <= min(div, MAX_POSTDIV); postdiv++) {
|
||||
prediv = div / postdiv;
|
||||
if (prediv < 1 || prediv > MAX_PREDIV)
|
||||
continue;
|
||||
|
||||
actual = (fpll / prediv) * (mult / postdiv);
|
||||
delta = (actual - data->pll_freq);
|
||||
if (delta < 0)
|
||||
delta = -delta;
|
||||
if ((delta < best_delta) || (best_delta == -1)) {
|
||||
best_delta = delta;
|
||||
best_mult = mult;
|
||||
best_pre = prediv;
|
||||
best_post = postdiv;
|
||||
if (delta == 0)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
if (best_delta == -1) {
|
||||
printf("pll cannot derive %lu from %lu\n",
|
||||
data->pll_freq, fpll);
|
||||
return;
|
||||
}
|
||||
|
||||
fpll = fpll * best_mult;
|
||||
fpll /= best_pre * best_post;
|
||||
|
||||
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLENSRC);
|
||||
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN);
|
||||
|
||||
pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
|
||||
|
||||
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
|
||||
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLDIS);
|
||||
|
||||
sspll_reg_write(data->pll, mult_factor, (best_mult - 1) << 8);
|
||||
sspll_reg_write(data->pll, prediv, best_pre - 1);
|
||||
sspll_reg_write(data->pll, postdiv, best_post - 1);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
if (data->div_freq[i])
|
||||
__pll_div_freq_set(data->pll, fpll, i,
|
||||
data->div_freq[i]);
|
||||
|
||||
pllctl_reg_write(data->pll, cmd, 1);
|
||||
|
||||
/* Wait until pll "go" operation completes */
|
||||
while (pllctl_reg_read(data->pll, stat) & 0x01);
|
||||
|
||||
pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
|
||||
pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN);
|
||||
}
|
||||
|
||||
void init_plls(int num_pll, struct pll_init_data *config)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_pll; i++)
|
||||
init_pll(&config[i]);
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* TNETV107X: Architecture initialization
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
void chip_configuration_unlock(void)
|
||||
{
|
||||
__raw_writel(TNETV107X_KICK0_MAGIC, TNETV107X_KICK0);
|
||||
__raw_writel(TNETV107X_KICK1_MAGIC, TNETV107X_KICK1);
|
||||
}
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
icache_enable();
|
||||
chip_configuration_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* TNETV107X: Low-level pre-relocation initialization
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
/* nothing for now, maybe needed for more exotic boot modes */
|
||||
mov pc, lr
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* TNETV107X: Pinmux configuration
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
#define MUX_MODE_1 0x00
|
||||
#define MUX_MODE_2 0x04
|
||||
#define MUX_MODE_3 0x0c
|
||||
#define MUX_MODE_4 0x1c
|
||||
|
||||
#define MUX_DEBUG 0
|
||||
|
||||
static const struct pin_config pin_table[] = {
|
||||
/* reg shift mode */
|
||||
TNETV107X_MUX_CFG(0, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(0, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(0, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(0, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(0, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(0, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(0, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(0, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(0, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(0, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(0, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(0, 25, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(1, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(1, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(1, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(1, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(1, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(1, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(1, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(1, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(1, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(1, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(1, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(1, 25, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(2, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(2, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(2, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(2, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(2, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(2, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(2, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(2, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(2, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(2, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(2, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(2, 25, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(3, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(3, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(3, 0, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(3, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(3, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(3, 5, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(3, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(3, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(3, 10, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(3, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(3, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(3, 15, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(3, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(3, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(3, 20, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(3, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(3, 25, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(3, 25, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(4, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(4, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(4, 0, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(4, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(4, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(4, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(4, 15, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(4, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(4, 20, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(4, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(4, 25, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(5, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(5, 0, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(5, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(5, 5, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(5, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(5, 10, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(5, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(5, 15, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(5, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(5, 20, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(5, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(5, 25, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(6, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(6, 0, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(6, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(6, 5, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(6, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(6, 10, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(6, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(6, 15, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(6, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(6, 20, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(6, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(6, 25, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(7, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(7, 0, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(7, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(7, 5, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(7, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(7, 10, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(7, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(7, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(7, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(7, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(7, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(7, 25, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(8, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(8, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(8, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(8, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(8, 5, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(8, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(8, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(9, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(9, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(9, 0, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(9, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(9, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(9, 5, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(9, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(9, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(9, 10, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(9, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(9, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(9, 15, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(9, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(9, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(9, 20, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(10, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(10, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(10, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(10, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(10, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(10, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(10, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(10, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(10, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(10, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(10, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(10, 25, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(11, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(11, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(12, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(12, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(12, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(12, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(12, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(12, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(13, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(13, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(13, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(13, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(14, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(14, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(14, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(14, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(14, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(14, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(15, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(15, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(15, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(15, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(15, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(15, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(15, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(15, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(16, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(16, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(16, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(16, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(16, 10, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(16, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(16, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(17, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(17, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(17, 0, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(17, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(17, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(17, 5, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(17, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(17, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(17, 10, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(17, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(17, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(17, 15, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(18, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(18, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(18, 0, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(18, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(18, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(18, 5, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(18, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(18, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(18, 10, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(18, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(18, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(18, 15, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(19, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(19, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(19, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(19, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(19, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(19, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(20, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(20, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(20, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(20, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(20, 15, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(20, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(20, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(21, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(21, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(21, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(21, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(21, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(21, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(22, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(22, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(22, 5, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(22, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(22, 10, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(22, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(22, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(22, 15, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(22, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(22, 20, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(22, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(22, 25, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(23, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(23, 0, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(23, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(23, 5, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(23, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(23, 10, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(24, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(24, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(24, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(24, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(24, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(24, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(24, 10, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(24, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(24, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(24, 15, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(24, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(24, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(24, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(24, 25, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(25, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(25, 0, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(25, 0, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(25, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(25, 5, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(25, 5, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(25, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(25, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(25, 10, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(25, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(25, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(25, 15, MUX_MODE_3),
|
||||
TNETV107X_MUX_CFG(25, 15, MUX_MODE_4),
|
||||
TNETV107X_MUX_CFG(26, 0, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(26, 5, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(26, 10, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(26, 10, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(26, 15, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(26, 15, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(26, 20, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(26, 20, MUX_MODE_2),
|
||||
TNETV107X_MUX_CFG(26, 25, MUX_MODE_1),
|
||||
TNETV107X_MUX_CFG(26, 25, MUX_MODE_2),
|
||||
};
|
||||
|
||||
const int pin_table_size = sizeof(pin_table) / sizeof(pin_table[0]);
|
||||
|
||||
int mux_select_pin(short index)
|
||||
{
|
||||
const struct pin_config *cfg;
|
||||
unsigned long mask, mode, reg;
|
||||
|
||||
if (index >= pin_table_size)
|
||||
return 0;
|
||||
|
||||
cfg = &pin_table[index];
|
||||
|
||||
mask = 0x1f << cfg->mask_offset;
|
||||
mode = cfg->mode << cfg->mask_offset;
|
||||
|
||||
reg = __raw_readl(TNETV107X_PINMUX(cfg->reg_index));
|
||||
reg = (reg & ~mask) | mode;
|
||||
__raw_writel(reg, TNETV107X_PINMUX(cfg->reg_index));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mux_select_pins(const short *pins)
|
||||
{
|
||||
int i, ret = 1;
|
||||
|
||||
for (i = 0; pins[i] >= 0; i++)
|
||||
ret &= mux_select_pin(pins[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* TNETV107X: Timer implementation
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
struct timer_regs {
|
||||
u_int32_t pid12;
|
||||
u_int32_t pad[3];
|
||||
u_int32_t tim12;
|
||||
u_int32_t tim34;
|
||||
u_int32_t prd12;
|
||||
u_int32_t prd34;
|
||||
u_int32_t tcr;
|
||||
u_int32_t tgcr;
|
||||
u_int32_t wdtcr;
|
||||
};
|
||||
|
||||
#define regs ((struct timer_regs *)CONFIG_SYS_TIMERBASE)
|
||||
|
||||
#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ)
|
||||
#define TIM_CLK_DIV 16
|
||||
|
||||
static ulong timestamp;
|
||||
static ulong lastinc;
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
clk_enable(TNETV107X_LPSC_TIMER0);
|
||||
|
||||
lastinc = timestamp = 0;
|
||||
|
||||
/* We are using timer34 in unchained 32-bit mode, full speed */
|
||||
__raw_writel(0x0, ®s->tcr);
|
||||
__raw_writel(0x0, ®s->tgcr);
|
||||
__raw_writel(0x06 | ((TIM_CLK_DIV - 1) << 8), ®s->tgcr);
|
||||
__raw_writel(0x0, ®s->tim34);
|
||||
__raw_writel(TIMER_LOAD_VAL, ®s->prd34);
|
||||
__raw_writel(2 << 22, ®s->tcr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong get_timer_raw(void)
|
||||
{
|
||||
ulong now = __raw_readl(®s->tim34);
|
||||
|
||||
if (now >= lastinc)
|
||||
timestamp += now - lastinc;
|
||||
else
|
||||
timestamp += now + TIMER_LOAD_VAL - lastinc;
|
||||
|
||||
lastinc = now;
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return (get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base;
|
||||
}
|
||||
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
ulong endtime;
|
||||
signed long diff;
|
||||
|
||||
tmo = CONFIG_SYS_HZ_CLOCK / 1000;
|
||||
tmo *= usec;
|
||||
tmo /= (1000 * TIM_CLK_DIV);
|
||||
|
||||
endtime = get_timer_raw() + tmo;
|
||||
|
||||
do {
|
||||
ulong now = get_timer_raw();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* TNETV107X: Watchdog timer implementation (for reset)
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
#define MAX_DIV 0xFFFE0001
|
||||
|
||||
struct wdt_regs {
|
||||
u32 kick_lock;
|
||||
#define KICK_LOCK_1 0x5555
|
||||
#define KICK_LOCK_2 0xaaaa
|
||||
u32 kick;
|
||||
|
||||
u32 change_lock;
|
||||
#define CHANGE_LOCK_1 0x6666
|
||||
#define CHANGE_LOCK_2 0xbbbb
|
||||
u32 change;
|
||||
|
||||
u32 disable_lock;
|
||||
#define DISABLE_LOCK_1 0x7777
|
||||
#define DISABLE_LOCK_2 0xcccc
|
||||
#define DISABLE_LOCK_3 0xdddd
|
||||
u32 disable;
|
||||
|
||||
u32 prescale_lock;
|
||||
#define PRESCALE_LOCK_1 0x5a5a
|
||||
#define PRESCALE_LOCK_2 0xa5a5
|
||||
u32 prescale;
|
||||
};
|
||||
|
||||
static struct wdt_regs* regs = (struct wdt_regs *)TNETV107X_WDT0_ARM_BASE;
|
||||
|
||||
#define wdt_reg_read(reg) __raw_readl(®s->reg)
|
||||
#define wdt_reg_write(reg, val) __raw_writel((val), ®s->reg)
|
||||
|
||||
static int write_prescale_reg(unsigned long prescale_value)
|
||||
{
|
||||
wdt_reg_write(prescale_lock, PRESCALE_LOCK_1);
|
||||
if ((wdt_reg_read(prescale_lock) & 0x3) != 0x1)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(prescale_lock, PRESCALE_LOCK_2);
|
||||
if ((wdt_reg_read(prescale_lock) & 0x3) != 0x3)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(prescale, prescale_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_change_reg(unsigned long initial_timer_value)
|
||||
{
|
||||
wdt_reg_write(change_lock, CHANGE_LOCK_1);
|
||||
if ((wdt_reg_read(change_lock) & 0x3) != 0x1)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(change_lock, CHANGE_LOCK_2);
|
||||
if ((wdt_reg_read(change_lock) & 0x3) != 0x3)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(change, initial_timer_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wdt_control(unsigned long disable_value)
|
||||
{
|
||||
wdt_reg_write(disable_lock, DISABLE_LOCK_1);
|
||||
if ((wdt_reg_read(disable_lock) & 0x3) != 0x1)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(disable_lock, DISABLE_LOCK_2);
|
||||
if ((wdt_reg_read(disable_lock) & 0x3) != 0x2)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(disable_lock, DISABLE_LOCK_3);
|
||||
if ((wdt_reg_read(disable_lock) & 0x3) != 0x3)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(disable, disable_value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wdt_set_period(unsigned long msec)
|
||||
{
|
||||
unsigned long change_value, count_value;
|
||||
unsigned long prescale_value = 1;
|
||||
unsigned long refclk_khz, maxdiv;
|
||||
int ret;
|
||||
|
||||
refclk_khz = clk_get_rate(TNETV107X_LPSC_WDT_ARM);
|
||||
maxdiv = (MAX_DIV / refclk_khz);
|
||||
|
||||
if ((!msec) || (msec > maxdiv))
|
||||
return -1;
|
||||
|
||||
count_value = refclk_khz * msec;
|
||||
if (count_value > 0xffff) {
|
||||
change_value = count_value / 0xffff + 1;
|
||||
prescale_value = count_value / change_value;
|
||||
} else {
|
||||
change_value = count_value;
|
||||
}
|
||||
|
||||
ret = write_prescale_reg(prescale_value - 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = write_change_reg(change_value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long last_wdt = -1;
|
||||
|
||||
int wdt_start(unsigned long msecs)
|
||||
{
|
||||
int ret;
|
||||
ret = wdt_control(0);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = wdt_set_period(msecs);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = wdt_control(1);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = wdt_kick();
|
||||
last_wdt = msecs;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wdt_stop(void)
|
||||
{
|
||||
last_wdt = -1;
|
||||
return wdt_control(0);
|
||||
}
|
||||
|
||||
int wdt_kick(void)
|
||||
{
|
||||
wdt_reg_write(kick_lock, KICK_LOCK_1);
|
||||
if ((wdt_reg_read(kick_lock) & 0x3) != 0x1)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(kick_lock, KICK_LOCK_2);
|
||||
if ((wdt_reg_read(kick_lock) & 0x3) != 0x3)
|
||||
return -1;
|
||||
|
||||
wdt_reg_write(kick, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
clk_enable(TNETV107X_LPSC_WDT_ARM);
|
||||
wdt_start(1);
|
||||
wdt_kick();
|
||||
}
|
||||
|
|
@ -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).o
|
||||
|
||||
START = start.o
|
||||
COBJS = interrupts.o 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)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# (C) Copyright 2002
|
||||
# Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
# Marius Groeger <mgroeger@sysgo.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-common -ffixed-r8 -msoft-float
|
||||
|
||||
PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi
|
||||
# =========================================================================
|
||||
#
|
||||
# Supply options according to compiler version
|
||||
#
|
||||
# =========================================================================
|
||||
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,\
|
||||
$(call cc-option,-malignment-traps,))
|
||||
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* (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>
|
||||
*
|
||||
* 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 <clps7111.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
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 ...
|
||||
* and we set the CPU-speed to 73 MHz - see start.S for details
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NETARM) || defined(CONFIG_S3C4510B) || defined(CONFIG_LPC2292)
|
||||
disable_interrupts ();
|
||||
/* Nothing more needed */
|
||||
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
|
||||
/* No cleanup before linux for IntegratorAP/CM720T as yet */
|
||||
#else
|
||||
#error No cleanup_before_linux() defined for this CPU type
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* (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>
|
||||
*
|
||||
* 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 <clps7111.h>
|
||||
#include <asm/proc-armv/ptrace.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#ifndef CONFIG_NETARM
|
||||
/* we always count down the max. */
|
||||
#define TIMER_LOAD_VAL 0xffff
|
||||
/* macro to read the 16 bit timer */
|
||||
#define READ_TIMER (IO_TC1D & 0xffff)
|
||||
|
||||
#ifdef CONFIG_LPC2292
|
||||
#undef READ_TIMER
|
||||
#define READ_TIMER (0xFFFFFFFF - GET32(T0TC))
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define IRQEN (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_INTR_ENABLE))
|
||||
#define TM2CTRL (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_CONTROL))
|
||||
#define TM2STAT (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_TIMER2_STATUS))
|
||||
#define TIMER_LOAD_VAL NETARM_GEN_TSTAT_CTC_MASK
|
||||
#define READ_TIMER (TM2STAT & NETARM_GEN_TSTAT_CTC_MASK)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_S3C4510B
|
||||
/* require interrupts for the S3C4510B */
|
||||
# ifndef CONFIG_USE_IRQ
|
||||
# error CONFIG_USE_IRQ _must_ be defined when using CONFIG_S3C4510B
|
||||
# else
|
||||
static struct _irq_handler IRQ_HANDLER[N_IRQS];
|
||||
# endif
|
||||
#endif /* CONFIG_S3C4510B */
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
void do_irq (struct pt_regs *pt_regs)
|
||||
{
|
||||
#if defined(CONFIG_S3C4510B)
|
||||
unsigned int pending;
|
||||
|
||||
while ( (pending = GET_REG( REG_INTOFFSET)) != 0x54) { /* sentinal value for no pending interrutps */
|
||||
IRQ_HANDLER[pending>>2].m_func( IRQ_HANDLER[pending>>2].m_data);
|
||||
|
||||
/* clear pending interrupt */
|
||||
PUT_REG( REG_INTPEND, (1<<(pending>>2)));
|
||||
}
|
||||
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
|
||||
/* No do_irq() for IntegratorAP/CM720T as yet */
|
||||
#elif defined(CONFIG_LPC2292)
|
||||
|
||||
void (*pfnct)(void);
|
||||
|
||||
pfnct = (void (*)(void))VICVectAddr;
|
||||
|
||||
(*pfnct)();
|
||||
#else
|
||||
#error do_irq() not defined for this CPU type
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_S3C4510B
|
||||
static void default_isr( void *data) {
|
||||
printf ("default_isr(): called for IRQ %d\n", (int)data);
|
||||
}
|
||||
|
||||
static void timer_isr( void *data) {
|
||||
unsigned int *pTime = (unsigned int *)data;
|
||||
|
||||
(*pTime)++;
|
||||
if ( !(*pTime % (CONFIG_SYS_HZ/4))) {
|
||||
/* toggle LED 0 */
|
||||
PUT_REG( REG_IOPDATA, GET_REG(REG_IOPDATA) ^ 0x1);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
|
||||
/* Use IntegratorAP routines in board/integratorap.c */
|
||||
#else
|
||||
|
||||
static ulong timestamp;
|
||||
static ulong lastdec;
|
||||
|
||||
#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C4510B)
|
||||
int arch_interrupt_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* install default interrupt handlers */
|
||||
for ( i = 0; i < N_IRQS; i++) {
|
||||
IRQ_HANDLER[i].m_data = (void *)i;
|
||||
IRQ_HANDLER[i].m_func = default_isr;
|
||||
}
|
||||
|
||||
/* configure interrupts for IRQ mode */
|
||||
PUT_REG( REG_INTMODE, 0x0);
|
||||
/* clear any pending interrupts */
|
||||
PUT_REG( REG_INTPEND, 0x1FFFFF);
|
||||
|
||||
lastdec = 0;
|
||||
|
||||
/* install interrupt handler for timer */
|
||||
IRQ_HANDLER[INT_TIMER0].m_data = (void *)×tamp;
|
||||
IRQ_HANDLER[INT_TIMER0].m_func = timer_isr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int timer_init (void)
|
||||
{
|
||||
#if defined(CONFIG_NETARM)
|
||||
/* disable all interrupts */
|
||||
IRQEN = 0;
|
||||
|
||||
/* operate timer 2 in non-prescale mode */
|
||||
TM2CTRL = ( NETARM_GEN_TIMER_SET_HZ(CONFIG_SYS_HZ) |
|
||||
NETARM_GEN_TCTL_ENABLE |
|
||||
NETARM_GEN_TCTL_INIT_COUNT(TIMER_LOAD_VAL));
|
||||
|
||||
/* set timer 2 counter */
|
||||
lastdec = TIMER_LOAD_VAL;
|
||||
#elif defined(CONFIG_S3C4510B)
|
||||
/* configure free running timer 0 */
|
||||
PUT_REG( REG_TMOD, 0x0);
|
||||
/* Stop timer 0 */
|
||||
CLR_REG( REG_TMOD, TM0_RUN);
|
||||
|
||||
/* Configure for interval mode */
|
||||
CLR_REG( REG_TMOD, TM1_TOGGLE);
|
||||
|
||||
/*
|
||||
* Load Timer data register with count down value.
|
||||
* count_down_val = CONFIG_SYS_SYS_CLK_FREQ/CONFIG_SYS_HZ
|
||||
*/
|
||||
PUT_REG( REG_TDATA0, (CONFIG_SYS_SYS_CLK_FREQ / CONFIG_SYS_HZ));
|
||||
|
||||
/*
|
||||
* Enable global interrupt
|
||||
* Enable timer0 interrupt
|
||||
*/
|
||||
CLR_REG( REG_INTMASK, ((1<<INT_GLOBAL) | (1<<INT_TIMER0)));
|
||||
|
||||
/* Start timer */
|
||||
SET_REG( REG_TMOD, TM0_RUN);
|
||||
#elif defined(CONFIG_LPC2292)
|
||||
PUT32(T0IR, 0); /* disable all timer0 interrupts */
|
||||
PUT32(T0TCR, 0); /* disable timer0 */
|
||||
PUT32(T0PR, CONFIG_SYS_SYS_CLK_FREQ / CONFIG_SYS_HZ);
|
||||
PUT32(T0MCR, 0);
|
||||
PUT32(T0TC, 0);
|
||||
PUT32(T0TCR, 1); /* enable timer0 */
|
||||
|
||||
#else
|
||||
#error No timer_init() defined for this CPU type
|
||||
#endif
|
||||
timestamp = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* ! IntegratorAP */
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
|
||||
|
||||
#if defined(CONFIG_NETARM) || defined(CONFIG_LPC2292)
|
||||
|
||||
ulong get_timer (ulong base)
|
||||
{
|
||||
return get_timer_masked () - base;
|
||||
}
|
||||
|
||||
void __udelay (unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
|
||||
tmo = usec / 1000;
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
tmo /= 1000;
|
||||
|
||||
tmo += get_timer (0);
|
||||
|
||||
while (get_timer_masked () < tmo)
|
||||
#ifdef CONFIG_LPC2292
|
||||
/* GJ - not sure whether this is really needed or a misunderstanding */
|
||||
__asm__ __volatile__(" nop");
|
||||
#else
|
||||
/*NOP*/;
|
||||
#endif
|
||||
}
|
||||
|
||||
ulong get_timer_masked (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;
|
||||
}
|
||||
|
||||
void udelay_masked (unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
ulong endtime;
|
||||
signed long diff;
|
||||
|
||||
if (usec >= 1000) {
|
||||
tmo = usec / 1000;
|
||||
tmo *= CONFIG_SYS_HZ;
|
||||
tmo /= 1000;
|
||||
} else {
|
||||
tmo = usec * CONFIG_SYS_HZ;
|
||||
tmo /= (1000*1000);
|
||||
}
|
||||
|
||||
endtime = get_timer_masked () + tmo;
|
||||
|
||||
do {
|
||||
ulong now = get_timer_masked ();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_S3C4510B)
|
||||
|
||||
ulong get_timer (ulong base)
|
||||
{
|
||||
return timestamp - base;
|
||||
}
|
||||
|
||||
void __udelay (unsigned long usec)
|
||||
{
|
||||
u32 ticks;
|
||||
|
||||
ticks = (usec * CONFIG_SYS_HZ) / 1000000;
|
||||
|
||||
ticks += get_timer (0);
|
||||
|
||||
while (get_timer (0) < ticks)
|
||||
/*NOP*/;
|
||||
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
|
||||
/* No timer routines for IntegratorAP/CM720T as yet */
|
||||
#else
|
||||
#error Timer routines not defined for this CPU type
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (C) Copyright 2000-2007
|
||||
# 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).o
|
||||
|
||||
COBJS = flash.o mmc.o mmc_hw.o spi.o
|
||||
SOBJS = $(obj)iap_entry.o
|
||||
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(call cmd_link_o_target, $(OBJS) $(SOBJS))
|
||||
|
||||
# this MUST be compiled as thumb code!
|
||||
$(SOBJS):
|
||||
$(CC) $(AFLAGS) -march=armv4t -c -o $(SOBJS) iap_entry.S
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* (C) Copyright 2006 Embedded Artists AB <www.embeddedartists.com>
|
||||
*
|
||||
* Modified to remove all but the IAP-command related code by
|
||||
* Gary Jennejohn <garyj@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
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
|
||||
/* IAP commands use 32 bytes at the top of CPU internal sram, we
|
||||
use 512 bytes below that */
|
||||
#define COPY_BUFFER_LOCATION 0x40003de0
|
||||
|
||||
#define IAP_LOCATION 0x7ffffff1
|
||||
#define IAP_CMD_PREPARE 50
|
||||
#define IAP_CMD_COPY 51
|
||||
#define IAP_CMD_ERASE 52
|
||||
#define IAP_CMD_CHECK 53
|
||||
#define IAP_CMD_ID 54
|
||||
#define IAP_CMD_VERSION 55
|
||||
#define IAP_CMD_COMPARE 56
|
||||
|
||||
#define IAP_RET_CMD_SUCCESS 0
|
||||
|
||||
static unsigned long command[5];
|
||||
static unsigned long result[2];
|
||||
|
||||
extern void iap_entry(unsigned long * command, unsigned long * result);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
static int get_flash_sector(flash_info_t * info, ulong flash_addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 1; i < (info->sector_count); i++) {
|
||||
if (flash_addr < (info->start[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
return (i-1);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* This function assumes that flash_addr is aligned on 512 bytes boundary
|
||||
* in flash. This function also assumes that prepare have been called
|
||||
* for the sector in question.
|
||||
*/
|
||||
int lpc2292_copy_buffer_to_flash(flash_info_t * info, ulong flash_addr)
|
||||
{
|
||||
int first_sector;
|
||||
int last_sector;
|
||||
|
||||
first_sector = get_flash_sector(info, flash_addr);
|
||||
last_sector = get_flash_sector(info, flash_addr + 512 - 1);
|
||||
|
||||
/* prepare sectors for write */
|
||||
command[0] = IAP_CMD_PREPARE;
|
||||
command[1] = first_sector;
|
||||
command[2] = last_sector;
|
||||
iap_entry(command, result);
|
||||
if (result[0] != IAP_RET_CMD_SUCCESS) {
|
||||
printf("IAP prepare failed\n");
|
||||
return ERR_PROG_ERROR;
|
||||
}
|
||||
|
||||
command[0] = IAP_CMD_COPY;
|
||||
command[1] = flash_addr;
|
||||
command[2] = COPY_BUFFER_LOCATION;
|
||||
command[3] = 512;
|
||||
command[4] = CONFIG_SYS_SYS_CLK_FREQ >> 10;
|
||||
iap_entry(command, result);
|
||||
if (result[0] != IAP_RET_CMD_SUCCESS) {
|
||||
printf("IAP copy failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int lpc2292_flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
int flag;
|
||||
int prot;
|
||||
int sect;
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect]) {
|
||||
prot++;
|
||||
}
|
||||
}
|
||||
if (prot)
|
||||
return ERR_PROTECTED;
|
||||
|
||||
|
||||
flag = disable_interrupts();
|
||||
|
||||
printf ("Erasing %d sectors starting at sector %2d.\n"
|
||||
"This make take some time ... ",
|
||||
s_last - s_first + 1, s_first);
|
||||
|
||||
command[0] = IAP_CMD_PREPARE;
|
||||
command[1] = s_first;
|
||||
command[2] = s_last;
|
||||
iap_entry(command, result);
|
||||
if (result[0] != IAP_RET_CMD_SUCCESS) {
|
||||
printf("IAP prepare failed\n");
|
||||
return ERR_PROTECTED;
|
||||
}
|
||||
|
||||
command[0] = IAP_CMD_ERASE;
|
||||
command[1] = s_first;
|
||||
command[2] = s_last;
|
||||
command[3] = CONFIG_SYS_SYS_CLK_FREQ >> 10;
|
||||
iap_entry(command, result);
|
||||
if (result[0] != IAP_RET_CMD_SUCCESS) {
|
||||
printf("IAP erase failed\n");
|
||||
return ERR_PROTECTED;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int lpc2292_write_buff (flash_info_t * info, uchar * src, ulong addr,
|
||||
ulong cnt)
|
||||
{
|
||||
int first_copy_size;
|
||||
int last_copy_size;
|
||||
int first_block;
|
||||
int last_block;
|
||||
int nbr_mid_blocks;
|
||||
uchar memmap_value;
|
||||
ulong i;
|
||||
uchar* src_org;
|
||||
uchar* dst_org;
|
||||
int ret = ERR_OK;
|
||||
|
||||
src_org = src;
|
||||
dst_org = (uchar*)addr;
|
||||
|
||||
first_block = addr / 512;
|
||||
last_block = (addr + cnt) / 512;
|
||||
nbr_mid_blocks = last_block - first_block - 1;
|
||||
|
||||
first_copy_size = 512 - (addr % 512);
|
||||
last_copy_size = (addr + cnt) % 512;
|
||||
|
||||
debug("\ncopy first block: (1) %lX -> %lX 0x200 bytes, "
|
||||
"(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX 0x200 bytes\n",
|
||||
(ulong)(first_block * 512),
|
||||
(ulong)COPY_BUFFER_LOCATION,
|
||||
(ulong)src,
|
||||
(ulong)(COPY_BUFFER_LOCATION + 512 - first_copy_size),
|
||||
first_copy_size,
|
||||
(ulong)COPY_BUFFER_LOCATION,
|
||||
(ulong)(first_block * 512));
|
||||
|
||||
/* copy first block */
|
||||
memcpy((void*)COPY_BUFFER_LOCATION,
|
||||
(void*)(first_block * 512), 512);
|
||||
memcpy((void*)(COPY_BUFFER_LOCATION + 512 - first_copy_size),
|
||||
src, first_copy_size);
|
||||
lpc2292_copy_buffer_to_flash(info, first_block * 512);
|
||||
src += first_copy_size;
|
||||
addr += first_copy_size;
|
||||
|
||||
/* copy middle blocks */
|
||||
for (i = 0; i < nbr_mid_blocks; i++) {
|
||||
debug("copy middle block: %lX -> %lX 512 bytes, "
|
||||
"%lX -> %lX 512 bytes\n",
|
||||
(ulong)src,
|
||||
(ulong)COPY_BUFFER_LOCATION,
|
||||
(ulong)COPY_BUFFER_LOCATION,
|
||||
(ulong)addr);
|
||||
|
||||
memcpy((void*)COPY_BUFFER_LOCATION, src, 512);
|
||||
lpc2292_copy_buffer_to_flash(info, addr);
|
||||
src += 512;
|
||||
addr += 512;
|
||||
}
|
||||
|
||||
|
||||
if (last_copy_size > 0) {
|
||||
debug("copy last block: (1) %lX -> %lX 0x200 bytes, "
|
||||
"(2) %lX -> %lX 0x%X bytes, (3) %lX -> %lX x200 bytes\n",
|
||||
(ulong)(last_block * 512),
|
||||
(ulong)COPY_BUFFER_LOCATION,
|
||||
(ulong)src,
|
||||
(ulong)(COPY_BUFFER_LOCATION),
|
||||
last_copy_size,
|
||||
(ulong)COPY_BUFFER_LOCATION,
|
||||
(ulong)addr);
|
||||
|
||||
/* copy last block */
|
||||
memcpy((void*)COPY_BUFFER_LOCATION,
|
||||
(void*)(last_block * 512), 512);
|
||||
memcpy((void*)COPY_BUFFER_LOCATION,
|
||||
src, last_copy_size);
|
||||
lpc2292_copy_buffer_to_flash(info, addr);
|
||||
}
|
||||
|
||||
/* verify write */
|
||||
memmap_value = GET8(MEMMAP);
|
||||
|
||||
disable_interrupts();
|
||||
|
||||
PUT8(MEMMAP, 01); /* we must make sure that initial 64
|
||||
bytes are taken from flash when we
|
||||
do the compare */
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
if (*dst_org != *src_org){
|
||||
printf("Write failed. Byte %lX differs\n", i);
|
||||
ret = ERR_PROG_ERROR;
|
||||
break;
|
||||
}
|
||||
dst_org++;
|
||||
src_org++;
|
||||
}
|
||||
|
||||
PUT8(MEMMAP, memmap_value);
|
||||
enable_interrupts();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
IAP_ADDRESS: .word 0x7FFFFFF1
|
||||
|
||||
.globl iap_entry
|
||||
iap_entry:
|
||||
ldr r2, IAP_ADDRESS
|
||||
bx r2
|
||||
mov pc, lr
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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 <common.h>
|
||||
#include <mmc.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <part.h>
|
||||
#include <fat.h>
|
||||
#include "mmc_hw.h"
|
||||
#include <asm/arch/spi.h>
|
||||
|
||||
#ifdef CONFIG_MMC
|
||||
|
||||
#undef MMC_DEBUG
|
||||
|
||||
static block_dev_desc_t mmc_dev;
|
||||
|
||||
/* these are filled out by a call to mmc_hw_get_parameters */
|
||||
static int hw_size; /* in kbytes */
|
||||
static int hw_nr_sects;
|
||||
static int hw_sect_size; /* in bytes */
|
||||
|
||||
block_dev_desc_t * mmc_get_dev(int dev)
|
||||
{
|
||||
return (block_dev_desc_t *)(&mmc_dev);
|
||||
}
|
||||
|
||||
unsigned long mmc_block_read(int dev,
|
||||
unsigned long start,
|
||||
lbaint_t blkcnt,
|
||||
void *buffer)
|
||||
{
|
||||
unsigned long rc = 0;
|
||||
unsigned char *p = (unsigned char *)buffer;
|
||||
unsigned long i;
|
||||
unsigned long addr = start;
|
||||
|
||||
#ifdef MMC_DEBUG
|
||||
printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start,
|
||||
(unsigned long)blkcnt);
|
||||
#endif
|
||||
|
||||
for(i = 0; i < (unsigned long)blkcnt; i++) {
|
||||
#ifdef MMC_DEBUG
|
||||
printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p);
|
||||
#endif
|
||||
(void)mmc_read_sector(addr, p);
|
||||
rc++;
|
||||
addr++;
|
||||
p += hw_sect_size;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Read hardware paramterers (sector size, size, number of sectors)
|
||||
*/
|
||||
static int mmc_hw_get_parameters(void)
|
||||
{
|
||||
unsigned char csddata[16];
|
||||
unsigned int sizemult;
|
||||
unsigned int size;
|
||||
|
||||
mmc_read_csd(csddata);
|
||||
hw_sect_size = 1<<(csddata[5] & 0x0f);
|
||||
size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0);
|
||||
sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1);
|
||||
hw_nr_sects = (size+1)*(1<<(sizemult+2));
|
||||
hw_size = hw_nr_sects*hw_sect_size/1024;
|
||||
|
||||
#ifdef MMC_DEBUG
|
||||
printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, "
|
||||
"hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mmc_legacy_init(int verbose)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (verbose)
|
||||
printf("mmc_legacy_init\n");
|
||||
|
||||
spi_init();
|
||||
/* this meeds to be done twice */
|
||||
mmc_hw_init();
|
||||
udelay(1000);
|
||||
mmc_hw_init();
|
||||
|
||||
mmc_hw_get_parameters();
|
||||
|
||||
mmc_dev.if_type = IF_TYPE_MMC;
|
||||
mmc_dev.part_type = PART_TYPE_DOS;
|
||||
mmc_dev.dev = 0;
|
||||
mmc_dev.lun = 0;
|
||||
mmc_dev.type = 0;
|
||||
mmc_dev.blksz = hw_sect_size;
|
||||
mmc_dev.lba = hw_nr_sects;
|
||||
sprintf((char*)mmc_dev.vendor, "Unknown vendor");
|
||||
sprintf((char*)mmc_dev.product, "Unknown product");
|
||||
sprintf((char*)mmc_dev.revision, "N/A");
|
||||
mmc_dev.removable = 0; /* should be true??? */
|
||||
mmc_dev.block_read = mmc_block_read;
|
||||
|
||||
fat_register_device(&mmc_dev, 1);
|
||||
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MMC */
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
This code was original written by Ulrich Radig and modified by
|
||||
Embedded Artists AB (www.embeddedartists.com).
|
||||
|
||||
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 <common.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/spi.h>
|
||||
|
||||
#define MMC_Enable() PUT32(IO1CLR, 1l << 22)
|
||||
#define MMC_Disable() PUT32(IO1SET, 1l << 22)
|
||||
#define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0);
|
||||
|
||||
static unsigned char Write_Command_MMC (unsigned char *CMD);
|
||||
static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer,
|
||||
unsigned short int Bytes);
|
||||
|
||||
/* initialize the hardware */
|
||||
int mmc_hw_init(void)
|
||||
{
|
||||
unsigned long a;
|
||||
unsigned short int Timeout = 0;
|
||||
unsigned char b;
|
||||
unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
|
||||
|
||||
/* set-up GPIO and SPI */
|
||||
(*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */
|
||||
(*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */
|
||||
|
||||
MMC_Disable();
|
||||
|
||||
spi_lock();
|
||||
spi_set_clock(248);
|
||||
spi_set_cfg(0, 1, 0);
|
||||
MMC_Enable();
|
||||
|
||||
/* waste some time */
|
||||
for(a=0; a < 20000; a++)
|
||||
asm("nop");
|
||||
|
||||
/* Put the MMC/SD-card into SPI-mode */
|
||||
for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */
|
||||
spi_write(0xff);
|
||||
|
||||
/* Sends command CMD0 to MMC/SD-card */
|
||||
while (Write_Command_MMC(CMD) != 1) {
|
||||
if (Timeout++ > 200) {
|
||||
MMC_Disable();
|
||||
spi_unlock();
|
||||
return(1); /* Abort with command 1 (return 1) */
|
||||
}
|
||||
}
|
||||
/* Sends Command CMD1 an MMC/SD-card */
|
||||
Timeout = 0;
|
||||
CMD[0] = 0x41;/* Command 1 */
|
||||
CMD[5] = 0xFF;
|
||||
|
||||
while (Write_Command_MMC(CMD) != 0) {
|
||||
if (Timeout++ > 200) {
|
||||
MMC_Disable();
|
||||
spi_unlock();
|
||||
return (2); /* Abort with command 2 (return 2) */
|
||||
}
|
||||
}
|
||||
|
||||
MMC_Disable();
|
||||
spi_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
Sends a command to the MMC/SD-card
|
||||
######################################################################### */
|
||||
static unsigned char Write_Command_MMC (unsigned char *CMD)
|
||||
{
|
||||
unsigned char a, tmp = 0xff;
|
||||
unsigned short int Timeout = 0;
|
||||
|
||||
MMC_Disable();
|
||||
spi_write(0xFF);
|
||||
MMC_Enable();
|
||||
|
||||
for (a = 0; a < 0x06; a++)
|
||||
spi_write(*CMD++);
|
||||
|
||||
while (tmp == 0xff) {
|
||||
tmp = spi_read();
|
||||
if (Timeout++ > 5000)
|
||||
break;
|
||||
}
|
||||
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
Routine to read the CID register from the MMC/SD-card (16 bytes)
|
||||
######################################################################### */
|
||||
void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short
|
||||
int Bytes)
|
||||
{
|
||||
unsigned short int a;
|
||||
|
||||
spi_lock();
|
||||
mmc_spi_cfg();
|
||||
MMC_Enable();
|
||||
|
||||
if (Write_Command_MMC(CMD) != 0) {
|
||||
MMC_Disable();
|
||||
spi_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
while (spi_read() != 0xfe) {};
|
||||
for (a = 0; a < Bytes; a++)
|
||||
*Buffer++ = spi_read();
|
||||
|
||||
/* Read the CRC-byte */
|
||||
spi_read(); /* CRC - byte is discarded */
|
||||
spi_read(); /* CRC - byte is discarded */
|
||||
/* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */
|
||||
MMC_Disable();
|
||||
spi_unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
Routine to read a block (512 bytes) from the MMC/SD-card
|
||||
######################################################################### */
|
||||
unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
|
||||
{
|
||||
/* Command 16 to read aBlocks from the MMC/SD - caed */
|
||||
unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
|
||||
|
||||
/* The address on the MMC/SD-card is in bytes,
|
||||
addr is transformed from blocks to bytes and the result is
|
||||
placed into the command */
|
||||
|
||||
addr = addr << 9; /* addr = addr * 512 */
|
||||
|
||||
CMD[1] = ((addr & 0xFF000000) >> 24);
|
||||
CMD[2] = ((addr & 0x00FF0000) >> 16);
|
||||
CMD[3] = ((addr & 0x0000FF00) >> 8 );
|
||||
|
||||
MMC_Read_Block(CMD, Buffer, 512);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ############################################################################
|
||||
Routine to write a block (512 byte) to the MMC/SD-card
|
||||
######################################################################### */
|
||||
unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
|
||||
{
|
||||
unsigned char tmp, a;
|
||||
unsigned short int b;
|
||||
/* Command 24 to write a block to the MMC/SD - card */
|
||||
unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
|
||||
|
||||
/* The address on the MMC/SD-card is in bytes,
|
||||
addr is transformed from blocks to bytes and the result is
|
||||
placed into the command */
|
||||
|
||||
addr = addr << 9; /* addr = addr * 512 */
|
||||
|
||||
CMD[1] = ((addr & 0xFF000000) >> 24);
|
||||
CMD[2] = ((addr & 0x00FF0000) >> 16);
|
||||
CMD[3] = ((addr & 0x0000FF00) >> 8 );
|
||||
|
||||
spi_lock();
|
||||
mmc_spi_cfg();
|
||||
MMC_Enable();
|
||||
|
||||
/* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */
|
||||
tmp = Write_Command_MMC(CMD);
|
||||
if (tmp != 0) {
|
||||
MMC_Disable();
|
||||
spi_unlock();
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
/* Do a short delay and send a clock-pulse to the MMC/SD-card */
|
||||
for (a = 0; a < 100; a++)
|
||||
spi_read();
|
||||
|
||||
/* Send a start byte to the MMC/SD-card */
|
||||
spi_write(0xFE);
|
||||
|
||||
/* Write the block (512 bytes) to the MMC/SD-card */
|
||||
for (b = 0; b < 512; b++)
|
||||
spi_write(*Buffer++);
|
||||
|
||||
/* write the CRC-Byte */
|
||||
spi_write(0xFF); /* write a dummy CRC */
|
||||
spi_write(0xFF); /* CRC code is not used */
|
||||
|
||||
/* Wait for MMC/SD-card busy */
|
||||
while (spi_read() != 0xff) {};
|
||||
|
||||
/* set MMC_Chip_Select to high (MMC/SD-card inactive) */
|
||||
MMC_Disable();
|
||||
spi_unlock();
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* #########################################################################
|
||||
Routine to read the CSD register from the MMC/SD-card (16 bytes)
|
||||
######################################################################### */
|
||||
unsigned char mmc_read_csd (unsigned char *Buffer)
|
||||
{
|
||||
/* Command to read the CSD register */
|
||||
unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF};
|
||||
|
||||
MMC_Read_Block(CMD, Buffer, 16);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
This module implements a linux character device driver for the 24c256 chip.
|
||||
Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com)
|
||||
|
||||
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 _MMC_HW_
|
||||
#define _MMC_HW_
|
||||
|
||||
unsigned char mmc_read_csd(unsigned char *Buffer);
|
||||
unsigned char mmc_read_sector (unsigned long addr,
|
||||
unsigned char *Buffer);
|
||||
unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer);
|
||||
int mmc_hw_init(void);
|
||||
|
||||
#endif /* _MMC_HW_ */
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
This module implements an interface to the SPI on the lpc22xx.
|
||||
Copyright (C) 2006 Embedded Artists AB (www.embeddedartists.com)
|
||||
|
||||
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 <common.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/spi.h>
|
||||
|
||||
unsigned long spi_flags;
|
||||
unsigned char spi_idle = 0x00;
|
||||
|
||||
int spi_init(void)
|
||||
{
|
||||
unsigned long pinsel0_value;
|
||||
|
||||
/* activate spi pins */
|
||||
pinsel0_value = GET32(PINSEL0);
|
||||
pinsel0_value &= ~(0xFFl << 8);
|
||||
pinsel0_value |= (0x55l << 8);
|
||||
PUT32(PINSEL0, pinsel0_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#
|
||||
# (C) Copyright 2000-2008
|
||||
# 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).o
|
||||
|
||||
COBJS-y += cache.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* (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>
|
||||
*
|
||||
* 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/hardware.h>
|
||||
|
||||
void icache_enable (void)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
/* disable all cache bits */
|
||||
CLR_REG( REG_SYSCFG, 0x3F);
|
||||
|
||||
/* 8KB cache, write enable */
|
||||
SET_REG( REG_SYSCFG, CACHE_WRITE_BUFF | CACHE_MODE_01);
|
||||
|
||||
/* clear TAG RAM bits */
|
||||
for ( i = 0; i < 256; i++)
|
||||
PUT_REG( CACHE_TAG_RAM + 4*i, 0x00000000);
|
||||
|
||||
/* clear SET0 RAM */
|
||||
for(i=0; i < 1024; i++)
|
||||
PUT_REG( CACHE_SET0_RAM + 4*i, 0x00000000);
|
||||
|
||||
/* clear SET1 RAM */
|
||||
for(i=0; i < 1024; i++)
|
||||
PUT_REG( CACHE_SET1_RAM + 4*i, 0x00000000);
|
||||
|
||||
/* enable cache */
|
||||
SET_REG( REG_SYSCFG, CACHE_ENABLE);
|
||||
|
||||
}
|
||||
|
||||
void icache_disable (void)
|
||||
{
|
||||
/* disable all cache bits */
|
||||
CLR_REG( REG_SYSCFG, 0x3F);
|
||||
}
|
||||
|
||||
int icache_status (void)
|
||||
{
|
||||
return GET_REG( REG_SYSCFG) & CACHE_ENABLE;
|
||||
}
|
||||
|
||||
void dcache_enable (void)
|
||||
{
|
||||
/* we don't have seperate instruction/data caches */
|
||||
icache_enable();
|
||||
}
|
||||
|
||||
void dcache_disable (void)
|
||||
{
|
||||
/* we don't have seperate instruction/data caches */
|
||||
icache_disable();
|
||||
}
|
||||
|
||||
int dcache_status (void)
|
||||
{
|
||||
/* we don't have seperate instruction/data caches */
|
||||
return icache_status();
|
||||
}
|
||||
|
|
@ -0,0 +1,625 @@
|
|||
/*
|
||||
* armboot - Startup Code for ARM720 CPU-core
|
||||
*
|
||||
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||
* Copyright (c) 2002 Alex Züpke <azu@sysgo.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 <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Jump vector table as in table 3.1 in [1]
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
.globl _start
|
||||
_start: b reset
|
||||
ldr pc, _undefined_instruction
|
||||
ldr pc, _software_interrupt
|
||||
ldr pc, _prefetch_abort
|
||||
ldr pc, _data_abort
|
||||
#ifdef CONFIG_LPC2292
|
||||
.word 0xB4405F76 /* 2's complement of the checksum of the vectors */
|
||||
#else
|
||||
ldr pc, _not_used
|
||||
#endif
|
||||
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
|
||||
|
||||
.balignl 16,0xdeadbeef
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Startup Code (reset vector)
|
||||
*
|
||||
* do important init only if we don't start from RAM!
|
||||
* relocate armboot to ram
|
||||
* setup stack
|
||||
* jump to second stage
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.globl _TEXT_BASE
|
||||
_TEXT_BASE:
|
||||
.word CONFIG_SYS_TEXT_BASE
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
* Subtracting _start from them lets the linker put their
|
||||
* relative position in the executable instead of leaving
|
||||
* them null.
|
||||
*/
|
||||
.globl _bss_start_ofs
|
||||
_bss_start_ofs:
|
||||
.word __bss_start - _start
|
||||
|
||||
.globl _bss_end_ofs
|
||||
_bss_end_ofs:
|
||||
.word __bss_end__ - _start
|
||||
|
||||
.globl _end_ofs
|
||||
_end_ofs:
|
||||
.word _end - _start
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
||||
.globl IRQ_STACK_START_IN
|
||||
IRQ_STACK_START_IN:
|
||||
.word 0x0badc0de
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0,cpsr
|
||||
bic r0,r0,#0x1f
|
||||
orr r0,r0,#0xd3
|
||||
msr cpsr,r0
|
||||
|
||||
/*
|
||||
* we do sys-critical inits only at reboot,
|
||||
* not when booting from ram!
|
||||
*/
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
bl cpu_init_crit
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LPC2292
|
||||
bl lowlevel_init
|
||||
#endif
|
||||
|
||||
/* Set stackpointer in internal RAM to call board_init_f */
|
||||
call_board_init_f:
|
||||
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
|
||||
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
|
||||
ldr r0,=0x00000000
|
||||
bl board_init_f
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* void relocate_code (addr_sp, gd, addr_moni)
|
||||
*
|
||||
* This "function" does not return, instead it continues in RAM
|
||||
* after relocating the monitor code.
|
||||
*
|
||||
*/
|
||||
.globl relocate_code
|
||||
relocate_code:
|
||||
mov r4, r0 /* save addr_sp */
|
||||
mov r5, r1 /* save addr of gd */
|
||||
mov r6, r2 /* save addr of destination */
|
||||
|
||||
/* Set up the stack */
|
||||
stack_setup:
|
||||
mov sp, r4
|
||||
|
||||
adr r0, _start
|
||||
cmp r0, r6
|
||||
beq clear_bss /* skip relocation */
|
||||
mov r1, r6 /* r1 <- scratch for copy_loop */
|
||||
ldr r3, _bss_start_ofs
|
||||
add r2, r0, r3 /* r2 <- source end address */
|
||||
|
||||
copy_loop:
|
||||
ldmia r0!, {r9-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r9-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
blo copy_loop
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* fix .rel.dyn relocations
|
||||
*/
|
||||
ldr r0, _TEXT_BASE /* r0 <- Text base */
|
||||
sub r9, r6, r0 /* r9 <- relocation offset */
|
||||
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
|
||||
add r10, r10, r0 /* r10 <- sym table in FLASH */
|
||||
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
|
||||
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
|
||||
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
|
||||
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
|
||||
fixloop:
|
||||
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
|
||||
add r0, r0, r9 /* r0 <- location to fix up in RAM */
|
||||
ldr r1, [r2, #4]
|
||||
and r7, r1, #0xff
|
||||
cmp r7, #23 /* relative fixup? */
|
||||
beq fixrel
|
||||
cmp r7, #2 /* absolute fixup? */
|
||||
beq fixabs
|
||||
/* ignore unknown type of fixup */
|
||||
b fixnext
|
||||
fixabs:
|
||||
/* absolute fix: set location to (offset) symbol value */
|
||||
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
|
||||
add r1, r10, r1 /* r1 <- address of symbol in table */
|
||||
ldr r1, [r1, #4] /* r1 <- symbol value */
|
||||
add r1, r1, r9 /* r1 <- relocated sym addr */
|
||||
b fixnext
|
||||
fixrel:
|
||||
/* relative fix: increase location by offset */
|
||||
ldr r1, [r0]
|
||||
add r1, r1, r9
|
||||
fixnext:
|
||||
str r1, [r0]
|
||||
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
|
||||
cmp r2, r3
|
||||
blo fixloop
|
||||
#endif
|
||||
|
||||
clear_bss:
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
ldr r0, _bss_start_ofs
|
||||
ldr r1, _bss_end_ofs
|
||||
mov r4, r6 /* reloc addr */
|
||||
add r0, r0, r4
|
||||
add r1, r1, r4
|
||||
mov r2, #0x00000000 /* clear */
|
||||
|
||||
clbss_l:cmp r0, r1 /* clear loop... */
|
||||
bhs clbss_e /* if reached end of bss, exit */
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
b clbss_l
|
||||
clbss_e:
|
||||
|
||||
bl coloured_LED_init
|
||||
bl red_led_on
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are done. Do not return, instead branch to second part of board
|
||||
* initialization, now running from RAM.
|
||||
*/
|
||||
ldr r0, _board_init_r_ofs
|
||||
adr r1, _start
|
||||
add lr, r0, r1
|
||||
add lr, lr, r9
|
||||
/* setup parameters for board_init_r */
|
||||
mov r0, r5 /* gd_t */
|
||||
mov r1, r6 /* dest_addr */
|
||||
/* jump to it ... */
|
||||
mov pc, lr
|
||||
|
||||
_board_init_r_ofs:
|
||||
.word board_init_r - _start
|
||||
|
||||
_rel_dyn_start_ofs:
|
||||
.word __rel_dyn_start - _start
|
||||
_rel_dyn_end_ofs:
|
||||
.word __rel_dyn_end - _start
|
||||
_dynsym_start_ofs:
|
||||
.word __dynsym_start - _start
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* CPU_init_critical registers
|
||||
*
|
||||
* setup important registers
|
||||
* setup memory timing
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_LPC2292)
|
||||
PLLCFG_ADR: .word PLLCFG
|
||||
PLLFEED_ADR: .word PLLFEED
|
||||
PLLCON_ADR: .word PLLCON
|
||||
PLLSTAT_ADR: .word PLLSTAT
|
||||
VPBDIV_ADR: .word VPBDIV
|
||||
MEMMAP_ADR: .word MEMMAP
|
||||
|
||||
#endif
|
||||
|
||||
cpu_init_crit:
|
||||
#if defined(CONFIG_NETARM)
|
||||
/*
|
||||
* prior to software reset : need to set pin PORTC4 to be *HRESET
|
||||
*/
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
ldr r1, =(NETARM_GEN_PORT_MODE(0x10) | \
|
||||
NETARM_GEN_PORT_DIR(0x10))
|
||||
str r1, [r0, #+NETARM_GEN_PORTC]
|
||||
/*
|
||||
* software reset : see HW Ref. Guide 8.2.4 : Software Service register
|
||||
* for an explanation of this process
|
||||
*/
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
/*
|
||||
* setup PLL and System Config
|
||||
*/
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
|
||||
ldr r1, =( NETARM_GEN_SYS_CFG_LENDIAN | \
|
||||
NETARM_GEN_SYS_CFG_BUSFULL | \
|
||||
NETARM_GEN_SYS_CFG_USER_EN | \
|
||||
NETARM_GEN_SYS_CFG_ALIGN_ABORT | \
|
||||
NETARM_GEN_SYS_CFG_BUSARB_INT | \
|
||||
NETARM_GEN_SYS_CFG_BUSMON_EN )
|
||||
|
||||
str r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL]
|
||||
|
||||
#ifndef CONFIG_NETARM_PLL_BYPASS
|
||||
ldr r1, =( NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \
|
||||
NETARM_GEN_PLL_CTL_POLTST_DEF | \
|
||||
NETARM_GEN_PLL_CTL_INDIV(1) | \
|
||||
NETARM_GEN_PLL_CTL_ICP_DEF | \
|
||||
NETARM_GEN_PLL_CTL_OUTDIV(2) )
|
||||
str r1, [r0, #+NETARM_GEN_PLL_CONTROL]
|
||||
#endif
|
||||
|
||||
/*
|
||||
* mask all IRQs by clearing all bits in the INTMRs
|
||||
*/
|
||||
mov r1, #0
|
||||
ldr r0, =NETARM_GEN_MODULE_BASE
|
||||
str r1, [r0, #+NETARM_GEN_INTR_ENABLE]
|
||||
|
||||
#elif defined(CONFIG_S3C4510B)
|
||||
|
||||
/*
|
||||
* Mask off all IRQ sources
|
||||
*/
|
||||
ldr r1, =REG_INTMASK
|
||||
ldr r0, =0x3FFFFF
|
||||
str r0, [r1]
|
||||
|
||||
/*
|
||||
* Disable Cache
|
||||
*/
|
||||
ldr r0, =REG_SYSCFG
|
||||
ldr r1, =0x83ffffa0 /* cache-disabled */
|
||||
str r1, [r0]
|
||||
|
||||
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
|
||||
/* No specific initialisation for IntegratorAP/CM720T as yet */
|
||||
#elif defined(CONFIG_LPC2292)
|
||||
/* Set-up PLL */
|
||||
mov r3, #0xAA
|
||||
mov r4, #0x55
|
||||
/* First disconnect and disable the PLL */
|
||||
ldr r0, PLLCON_ADR
|
||||
mov r1, #0x00
|
||||
str r1, [r0]
|
||||
ldr r0, PLLFEED_ADR /* start feed sequence */
|
||||
str r3, [r0]
|
||||
str r4, [r0] /* feed sequence done */
|
||||
/* Set new M and P values */
|
||||
ldr r0, PLLCFG_ADR
|
||||
mov r1, #0x23 /* M=4 and P=2 */
|
||||
str r1, [r0]
|
||||
ldr r0, PLLFEED_ADR /* start feed sequence */
|
||||
str r3, [r0]
|
||||
str r4, [r0] /* feed sequence done */
|
||||
/* Then enable the PLL */
|
||||
ldr r0, PLLCON_ADR
|
||||
mov r1, #0x01 /* PLL enable bit */
|
||||
str r1, [r0]
|
||||
ldr r0, PLLFEED_ADR /* start feed sequence */
|
||||
str r3, [r0]
|
||||
str r4, [r0] /* feed sequence done */
|
||||
/* Wait for the lock */
|
||||
ldr r0, PLLSTAT_ADR
|
||||
mov r1, #0x400 /* lock bit */
|
||||
lock_loop:
|
||||
ldr r2, [r0]
|
||||
and r2, r1, r2
|
||||
cmp r2, #0
|
||||
beq lock_loop
|
||||
/* And finally connect the PLL */
|
||||
ldr r0, PLLCON_ADR
|
||||
mov r1, #0x03 /* PLL enable bit and connect bit */
|
||||
str r1, [r0]
|
||||
ldr r0, PLLFEED_ADR /* start feed sequence */
|
||||
str r3, [r0]
|
||||
str r4, [r0] /* feed sequence done */
|
||||
/* Set-up VPBDIV register */
|
||||
ldr r0, VPBDIV_ADR
|
||||
mov r1, #0x01 /* VPB clock is same as process clock */
|
||||
str r1, [r0]
|
||||
#else
|
||||
#error No cpu_init_crit() defined for current CPU type
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM7_REVD
|
||||
/* set clock speed */
|
||||
/* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */
|
||||
/* !!! not doing DRAM refresh properly! */
|
||||
ldr r0, SYSCON3
|
||||
ldr r1, [r0]
|
||||
bic r1, r1, #CLKCTL
|
||||
orr r1, r1, #CLKCTL_36
|
||||
str r1, [r0]
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LPC2292
|
||||
mov ip, lr
|
||||
/*
|
||||
* before relocating, we have to setup RAM timing
|
||||
* because memory timing is board-dependent, you will
|
||||
* find a lowlevel_init.S in your board directory.
|
||||
*/
|
||||
bl lowlevel_init
|
||||
mov lr, ip
|
||||
#endif
|
||||
|
||||
mov pc, lr
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* 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 ...
|
||||
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
|
||||
*/
|
||||
|
||||
.macro bad_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
add r8, sp, #S_PC
|
||||
|
||||
ldr r2, IRQ_STACK_START_IN
|
||||
ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
|
||||
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
|
||||
|
||||
add r5, sp, #S_SP
|
||||
mov r1, lr
|
||||
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
add r8, sp, #S_PC
|
||||
stmdb r8, {sp, lr}^ @ Calling SP, LR
|
||||
str lr, [r8, #0] @ Save calling PC
|
||||
mrs r6, spsr
|
||||
str r6, [r8, #4] @ Save CPSR
|
||||
str r0, [r8, #8] @ Save OLD_R0
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_restore_user_regs
|
||||
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
|
||||
mov r0, r0
|
||||
ldr lr, [sp, #S_PC] @ Get PC
|
||||
add sp, sp, #S_FRAME_SIZE
|
||||
subs pc, lr, #4 @ return & move spsr_svc into cpsr
|
||||
.endm
|
||||
|
||||
.macro get_bad_stack
|
||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
||||
|
||||
str lr, [r13] @ save caller lr / spsr
|
||||
mrs lr, spsr
|
||||
str lr, [r13, #4]
|
||||
|
||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
||||
msr spsr_c, r13
|
||||
mov lr, pc
|
||||
movs pc, lr
|
||||
.endm
|
||||
|
||||
.macro get_irq_stack @ setup IRQ stack
|
||||
ldr sp, IRQ_STACK_START
|
||||
.endm
|
||||
|
||||
.macro get_fiq_stack @ setup FIQ stack
|
||||
ldr sp, FIQ_STACK_START
|
||||
.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
|
||||
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
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_irq_stack
|
||||
irq_save_user_regs
|
||||
bl do_irq
|
||||
irq_restore_user_regs
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_fiq_stack
|
||||
/* someone ought to write a more effiction fiq_save_user_regs */
|
||||
irq_save_user_regs
|
||||
bl do_fiq
|
||||
irq_restore_user_regs
|
||||
|
||||
#else
|
||||
|
||||
.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
|
||||
|
||||
#if defined(CONFIG_NETARM)
|
||||
.align 5
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
ldr r1, =NETARM_MEM_MODULE_BASE
|
||||
ldr r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR]
|
||||
ldr r1, =0xFFFFF000
|
||||
and r0, r1, r0
|
||||
ldr r1, =(relocate-CONFIG_SYS_TEXT_BASE)
|
||||
add r0, r1, r0
|
||||
ldr r4, =NETARM_GEN_MODULE_BASE
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETA
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
ldr r1, =NETARM_GEN_SW_SVC_RESETB
|
||||
str r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
|
||||
mov pc, r0
|
||||
#elif defined(CONFIG_S3C4510B)
|
||||
/* Nothing done here as reseting the CPU is board specific, depending
|
||||
* on external peripherals such as watchdog timers, etc. */
|
||||
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
|
||||
/* No specific reset actions for IntegratorAP/CM720T as yet */
|
||||
#elif defined(CONFIG_LPC2292)
|
||||
.align 5
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
mov pc, r0
|
||||
#else
|
||||
#error No reset_cpu() defined for current CPU type
|
||||
#endif
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#
|
||||
# (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).o
|
||||
|
||||
START = start.o
|
||||
|
||||
COBJS-y += cpu.o
|
||||
COBJS-$(CONFIG_USE_IRQ) += interrupts.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
|
||||
all: $(obj).depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# (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$(SOC).o
|
||||
|
||||
SOBJS += reset.o
|
||||
COBJS += timer.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* (C) Copyright 2009 Faraday Technology
|
||||
* Po-Yu Chuang <ratbert@faraday-tech.com>
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
.global reset_cpu
|
||||
reset_cpu:
|
||||
b reset_cpu
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* (C) Copyright 2009 Faraday Technology
|
||||
* Po-Yu Chuang <ratbert@faraday-tech.com>
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <div64.h>
|
||||
#include <asm/io.h>
|
||||
#include <faraday/ftpmu010.h>
|
||||
#include <faraday/fttmr010.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define TIMER_CLOCK 32768
|
||||
#define TIMER_LOAD_VAL 0xffffffff
|
||||
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
tick *= CONFIG_SYS_HZ;
|
||||
do_div(tick, gd->timer_rate_hz);
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long usec_to_tick(unsigned long long usec)
|
||||
{
|
||||
usec *= gd->timer_rate_hz;
|
||||
do_div(usec, 1000000);
|
||||
|
||||
return usec;
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
|
||||
unsigned int cr;
|
||||
|
||||
debug("%s()\n", __func__);
|
||||
|
||||
/* disable timers */
|
||||
writel(0, &tmr->cr);
|
||||
|
||||
/* use 32768Hz oscillator for RTC, WDT, TIMER */
|
||||
ftpmu010_32768osc_enable();
|
||||
|
||||
/* setup timer */
|
||||
writel(TIMER_LOAD_VAL, &tmr->timer3_load);
|
||||
writel(TIMER_LOAD_VAL, &tmr->timer3_counter);
|
||||
writel(0, &tmr->timer3_match1);
|
||||
writel(0, &tmr->timer3_match2);
|
||||
|
||||
/* we don't want timer to issue interrupts */
|
||||
writel(FTTMR010_TM3_MATCH1 |
|
||||
FTTMR010_TM3_MATCH2 |
|
||||
FTTMR010_TM3_OVERFLOW,
|
||||
&tmr->interrupt_mask);
|
||||
|
||||
cr = readl(&tmr->cr);
|
||||
cr |= FTTMR010_TM3_CLOCK; /* use external clock */
|
||||
cr |= FTTMR010_TM3_ENABLE;
|
||||
writel(cr, &tmr->cr);
|
||||
|
||||
gd->timer_rate_hz = TIMER_CLOCK;
|
||||
gd->tbu = gd->tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current 64 bit timer tick count
|
||||
*/
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
struct fttmr010 *tmr = (struct fttmr010 *)CONFIG_FTTMR010_BASE;
|
||||
ulong now = TIMER_LOAD_VAL - readl(&tmr->timer3_counter);
|
||||
|
||||
/* increment tbu if tbl has rolled over */
|
||||
if (now < gd->tbl)
|
||||
gd->tbu++;
|
||||
gd->tbl = now;
|
||||
return (((unsigned long long)gd->tbu) << 32) | gd->tbl;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
unsigned long long start;
|
||||
ulong tmo;
|
||||
|
||||
start = get_ticks(); /* get current timestamp */
|
||||
tmo = usec_to_tick(usec); /* convert usecs to ticks */
|
||||
while ((get_ticks() - start) < tmo)
|
||||
; /* loop till time has passed */
|
||||
}
|
||||
|
||||
/*
|
||||
* get_timer(base) can be used to check for timeouts or
|
||||
* to measure elasped time relative to an event:
|
||||
*
|
||||
* ulong start_time = get_timer(0) sets start_time to the current
|
||||
* time value.
|
||||
* get_timer(start_time) returns the time elapsed since then.
|
||||
*
|
||||
* The time is used in CONFIG_SYS_HZ units!
|
||||
*/
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return tick_to_time(get_ticks()) - base;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of timer ticks per second.
|
||||
*/
|
||||
ulong get_tbclk(void)
|
||||
{
|
||||
return gd->timer_rate_hz;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (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$(SOC).o
|
||||
|
||||
SOBJS += lowlevel_init.o
|
||||
COBJS += reset.o
|
||||
COBJS += timer.o
|
||||
COBJS += clock.o
|
||||
COBJS += cpu.o
|
||||
COBJS += at91rm9200_devices.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* [partely copied from arch/arm/cpu/arm926ejs/at91/arm9260_devices.c]
|
||||
*
|
||||
* (C) Copyright 2011
|
||||
* Andreas Bießmann <andreas.devel@googlemail.com>
|
||||
*
|
||||
* (C) Copyright 2007-2008
|
||||
* Stelian Pop <stelian@popies.net>
|
||||
* Lead Tech Design <www.leadtechdesign.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/io.h>
|
||||
#include <asm/arch/at91_common.h>
|
||||
#include <asm/arch/at91_pmc.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
/*
|
||||
* if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all
|
||||
* peripheral pins. Good to have if hardware is soldered optionally
|
||||
* or in case of SPI no slave is selected. Avoid lines to float
|
||||
* needlessly. Use a short local PUP define.
|
||||
*
|
||||
* Due to errata "TXD floats when CTS is inactive" pullups are always
|
||||
* on for TXD pins.
|
||||
*/
|
||||
#ifdef CONFIG_AT91_GPIO_PULLUP
|
||||
# define PUP CONFIG_AT91_GPIO_PULLUP
|
||||
#else
|
||||
# define PUP 0
|
||||
#endif
|
||||
|
||||
void at91_serial0_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 17, 1); /* TXD0 */
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 18, PUP); /* RXD0 */
|
||||
writel(1 << ATMEL_ID_USART0, &pmc->pcer);
|
||||
}
|
||||
|
||||
void at91_serial1_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 20, PUP); /* RXD1 */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 21, 1); /* TXD1 */
|
||||
writel(1 << ATMEL_ID_USART1, &pmc->pcer);
|
||||
}
|
||||
|
||||
void at91_serial2_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *)ATMEL_BASE_PMC;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 22, PUP); /* RXD2 */
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 23, 1); /* TXD2 */
|
||||
writel(1 << ATMEL_ID_USART2, &pmc->pcer);
|
||||
}
|
||||
|
||||
void at91_seriald_hw_init(void)
|
||||
{
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 30, PUP); /* DRXD */
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 31, 1); /* DTXD */
|
||||
/* writing SYS to PCER has no effect on AT91RM9200 */
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* [origin: Linux kernel linux/arch/arm/mach-at91/clock.c]
|
||||
*
|
||||
* Copyright (C) 2011 Andreas Bießmann
|
||||
* Copyright (C) 2005 David Brownell
|
||||
* Copyright (C) 2005 Ivan Kokshaysky
|
||||
* Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/at91_pmc.h>
|
||||
#include <asm/arch/clk.h>
|
||||
|
||||
#if !defined(CONFIG_AT91FAMILY)
|
||||
# error You need to define CONFIG_AT91FAMILY in your board config!
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static unsigned long at91_css_to_rate(unsigned long css)
|
||||
{
|
||||
switch (css) {
|
||||
case AT91_PMC_MCKR_CSS_SLOW:
|
||||
return CONFIG_SYS_AT91_SLOW_CLOCK;
|
||||
case AT91_PMC_MCKR_CSS_MAIN:
|
||||
return gd->main_clk_rate_hz;
|
||||
case AT91_PMC_MCKR_CSS_PLLA:
|
||||
return gd->plla_rate_hz;
|
||||
case AT91_PMC_MCKR_CSS_PLLB:
|
||||
return gd->pllb_rate_hz;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_ATMEL
|
||||
static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq)
|
||||
{
|
||||
unsigned i, div = 0, mul = 0, diff = 1 << 30;
|
||||
unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
|
||||
|
||||
/* PLL output max 240 MHz (or 180 MHz per errata) */
|
||||
if (out_freq > 240000000)
|
||||
goto fail;
|
||||
|
||||
for (i = 1; i < 256; i++) {
|
||||
int diff1;
|
||||
unsigned input, mul1;
|
||||
|
||||
/*
|
||||
* PLL input between 1MHz and 32MHz per spec, but lower
|
||||
* frequences seem necessary in some cases so allow 100K.
|
||||
* Warning: some newer products need 2MHz min.
|
||||
*/
|
||||
input = main_freq / i;
|
||||
if (input < 100000)
|
||||
continue;
|
||||
if (input > 32000000)
|
||||
continue;
|
||||
|
||||
mul1 = out_freq / input;
|
||||
if (mul1 > 2048)
|
||||
continue;
|
||||
if (mul1 < 2)
|
||||
goto fail;
|
||||
|
||||
diff1 = out_freq - input * mul1;
|
||||
if (diff1 < 0)
|
||||
diff1 = -diff1;
|
||||
if (diff > diff1) {
|
||||
diff = diff1;
|
||||
div = i;
|
||||
mul = mul1;
|
||||
if (diff == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 256 && diff > (out_freq >> 5))
|
||||
goto fail;
|
||||
return ret | ((mul - 1) << 16) | div;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 at91_pll_rate(u32 freq, u32 reg)
|
||||
{
|
||||
unsigned mul, div;
|
||||
|
||||
div = reg & 0xff;
|
||||
mul = (reg >> 16) & 0x7ff;
|
||||
if (div && mul) {
|
||||
freq /= div;
|
||||
freq *= mul + 1;
|
||||
} else
|
||||
freq = 0;
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
int at91_clock_init(unsigned long main_clock)
|
||||
{
|
||||
unsigned freq, mckr;
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
|
||||
#ifndef CONFIG_SYS_AT91_MAIN_CLOCK
|
||||
unsigned tmp;
|
||||
/*
|
||||
* When the bootloader initialized the main oscillator correctly,
|
||||
* there's no problem using the cycle counter. But if it didn't,
|
||||
* or when using oscillator bypass mode, we must be told the speed
|
||||
* of the main clock.
|
||||
*/
|
||||
if (!main_clock) {
|
||||
do {
|
||||
tmp = readl(&pmc->mcfr);
|
||||
} while (!(tmp & AT91_PMC_MCFR_MAINRDY));
|
||||
tmp &= AT91_PMC_MCFR_MAINF_MASK;
|
||||
main_clock = tmp * (CONFIG_SYS_AT91_SLOW_CLOCK / 16);
|
||||
}
|
||||
#endif
|
||||
gd->main_clk_rate_hz = main_clock;
|
||||
|
||||
/* report if PLLA is more than mildly overclocked */
|
||||
gd->plla_rate_hz = at91_pll_rate(main_clock, readl(&pmc->pllar));
|
||||
|
||||
#ifdef CONFIG_USB_ATMEL
|
||||
/*
|
||||
* USB clock init: choose 48 MHz PLLB value,
|
||||
* disable 48MHz clock during usb peripheral suspend.
|
||||
*
|
||||
* REVISIT: assumes MCK doesn't derive from PLLB!
|
||||
*/
|
||||
gd->at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) |
|
||||
AT91_PMC_PLLBR_USBDIV_2;
|
||||
gd->pllb_rate_hz = at91_pll_rate(main_clock, gd->at91_pllb_usb_init);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MCK and CPU derive from one of those primary clocks.
|
||||
* For now, assume this parentage won't change.
|
||||
*/
|
||||
mckr = readl(&pmc->mckr);
|
||||
gd->mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
|
||||
freq = gd->mck_rate_hz;
|
||||
|
||||
freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2)); /* prescale */
|
||||
/* mdiv */
|
||||
gd->mck_rate_hz = freq / (1 + ((mckr & AT91_PMC_MCKR_MDIV_MASK) >> 8));
|
||||
gd->cpu_clk_rate_hz = freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* [origin: arch/arm/cpu/arm926ejs/at91/cpu.c]
|
||||
*
|
||||
* (C) Copyright 2011
|
||||
* Andreas Bießmann, andreas.devel@googlemail.com
|
||||
* (C) Copyright 2010
|
||||
* Reinhard Meyer, reinhard.meyer@emk-elektronik.de
|
||||
* (C) Copyright 2009
|
||||
* Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.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/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/clk.h>
|
||||
|
||||
#ifndef CONFIG_SYS_AT91_MAIN_CLOCK
|
||||
#define CONFIG_SYS_AT91_MAIN_CLOCK 0
|
||||
#endif
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
return at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
|
||||
* Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
|
||||
*
|
||||
* Modified for the at91rm9200dk board by
|
||||
* (C) Copyright 2004
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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>
|
||||
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/at91_mc.h>
|
||||
#include <asm/arch/at91_pmc.h>
|
||||
#include <asm/arch/at91_pio.h>
|
||||
|
||||
#define ARM920T_CONTROL 0xC0000000 /* @ set bit 31 (iA) and 30 (nF) */
|
||||
|
||||
_MTEXT_BASE:
|
||||
#undef START_FROM_MEM
|
||||
#ifdef START_FROM_MEM
|
||||
.word CONFIG_SYS_TEXT_BASE-PHYS_FLASH_1
|
||||
#else
|
||||
.word CONFIG_SYS_TEXT_BASE
|
||||
#endif
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
ldr r1, =AT91_ASM_PMC_MOR
|
||||
/* Main oscillator Enable register */
|
||||
#ifdef CONFIG_SYS_USE_MAIN_OSCILLATOR
|
||||
ldr r0, =0x0000FF01 /* Enable main oscillator */
|
||||
#else
|
||||
ldr r0, =0x0000FF00 /* Disable main oscillator */
|
||||
#endif
|
||||
str r0, [r1] /*AT91C_CKGR_MOR] */
|
||||
/* Add loop to compensate Main Oscillator startup time */
|
||||
ldr r0, =0x00000010
|
||||
LoopOsc:
|
||||
subs r0, r0, #1
|
||||
bhi LoopOsc
|
||||
|
||||
/* memory control configuration */
|
||||
/* this isn't very elegant, but what the heck */
|
||||
ldr r0, =SMRDATA
|
||||
ldr r1, _MTEXT_BASE
|
||||
sub r0, r0, r1
|
||||
ldr r2, =SMRDATAE
|
||||
sub r2, r2, r1
|
||||
pllloop:
|
||||
/* the address */
|
||||
ldr r1, [r0], #4
|
||||
/* the value */
|
||||
ldr r3, [r0], #4
|
||||
str r3, [r1]
|
||||
cmp r2, r0
|
||||
bne pllloop
|
||||
/* delay - this is all done by guess */
|
||||
ldr r0, =0x00010000
|
||||
/* (vs reading PMC_SR for LOCKA, LOCKB ... or MOSCS earlier) */
|
||||
lock:
|
||||
subs r0, r0, #1
|
||||
bhi lock
|
||||
ldr r0, =SMRDATA1
|
||||
ldr r1, _MTEXT_BASE
|
||||
sub r0, r0, r1
|
||||
ldr r2, =SMRDATA1E
|
||||
sub r2, r2, r1
|
||||
sdinit:
|
||||
/* the address */
|
||||
ldr r1, [r0], #4
|
||||
/* the value */
|
||||
ldr r3, [r0], #4
|
||||
str r3, [r1]
|
||||
cmp r2, r0
|
||||
bne sdinit
|
||||
|
||||
/* switch from FastBus to Asynchronous clock mode */
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
orr r0, r0, #ARM920T_CONTROL
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/* everything is fine now */
|
||||
mov pc, lr
|
||||
|
||||
.ltorg
|
||||
|
||||
SMRDATA:
|
||||
.word AT91_ASM_MC_EBI_CFG
|
||||
.word CONFIG_SYS_EBI_CFGR_VAL
|
||||
.word AT91_ASM_MC_SMC_CSR0
|
||||
.word CONFIG_SYS_SMC_CSR0_VAL
|
||||
.word AT91_ASM_PMC_PLLAR
|
||||
.word CONFIG_SYS_PLLAR_VAL
|
||||
.word AT91_ASM_PMC_PLLBR
|
||||
.word CONFIG_SYS_PLLBR_VAL
|
||||
.word AT91_ASM_PMC_MCKR
|
||||
.word CONFIG_SYS_MCKR_VAL
|
||||
SMRDATAE:
|
||||
/* here there's a delay */
|
||||
SMRDATA1:
|
||||
.word AT91_ASM_PIOC_ASR
|
||||
.word CONFIG_SYS_PIOC_ASR_VAL
|
||||
.word AT91_ASM_PIOC_BSR
|
||||
.word CONFIG_SYS_PIOC_BSR_VAL
|
||||
.word AT91_ASM_PIOC_PDR
|
||||
.word CONFIG_SYS_PIOC_PDR_VAL
|
||||
.word AT91_ASM_MC_EBI_CSA
|
||||
.word CONFIG_SYS_EBI_CSA_VAL
|
||||
.word AT91_ASM_MC_SDRAMC_CR
|
||||
.word CONFIG_SYS_SDRC_CR_VAL
|
||||
.word AT91_ASM_MC_SDRAMC_MR
|
||||
.word CONFIG_SYS_SDRC_MR_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word AT91_ASM_MC_SDRAMC_MR
|
||||
.word CONFIG_SYS_SDRC_MR_VAL1
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word AT91_ASM_MC_SDRAMC_MR
|
||||
.word CONFIG_SYS_SDRC_MR_VAL2
|
||||
.word CONFIG_SYS_SDRAM1
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word AT91_ASM_MC_SDRAMC_TR
|
||||
.word CONFIG_SYS_SDRC_TR_VAL
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
.word AT91_ASM_MC_SDRAMC_MR
|
||||
.word CONFIG_SYS_SDRC_MR_VAL3
|
||||
.word CONFIG_SYS_SDRAM
|
||||
.word CONFIG_SYS_SDRAM_VAL
|
||||
SMRDATA1E:
|
||||
/* SMRDATA1 is 176 bytes long */
|
||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Lineo, Inc. <www.lineo.com>
|
||||
* Bernhard Kuhn <bkuhn@lineo.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>
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/at91_st.h>
|
||||
|
||||
void __attribute__((weak)) board_reset(void)
|
||||
{
|
||||
/* true empty function for defining weak symbol */
|
||||
}
|
||||
|
||||
void reset_cpu(ulong ignored)
|
||||
{
|
||||
at91_st_t *st = (at91_st_t *) ATMEL_BASE_ST;
|
||||
|
||||
board_reset();
|
||||
|
||||
/* Reset the cpu by setting up the watchdog timer */
|
||||
writel(AT91_ST_WDMR_RSTEN | AT91_ST_WDMR_EXTEN | AT91_ST_WDMR_WDV(2),
|
||||
&st->wdmr);
|
||||
writel(AT91_ST_CR_WDRST, &st->cr);
|
||||
/* and let it timeout */
|
||||
while (1)
|
||||
;
|
||||
/* Never reached */
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Lineo, Inc. <www.lineo.com>
|
||||
* Bernhard Kuhn <bkuhn@lineo.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>
|
||||
*
|
||||
* 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/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/at91_tc.h>
|
||||
#include <asm/arch/at91_pmc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* the number of clocks per CONFIG_SYS_HZ */
|
||||
#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ)
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC;
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
|
||||
|
||||
/* enables TC1.0 clock */
|
||||
writel(1 << ATMEL_ID_TC0, &pmc->pcer); /* enable clock */
|
||||
|
||||
writel(0, &tc->bcr);
|
||||
writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE |
|
||||
AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr);
|
||||
|
||||
writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr);
|
||||
/* set to MCLK/2 and restart the timer
|
||||
when the value in TC_RC is reached */
|
||||
writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr);
|
||||
|
||||
writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interrupts */
|
||||
writel(TIMER_LOAD_VAL, &tc->tc[0].rc);
|
||||
|
||||
writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr);
|
||||
gd->lastinc = 0;
|
||||
gd->tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
udelay_masked(usec);
|
||||
}
|
||||
|
||||
ulong get_timer_raw(void)
|
||||
{
|
||||
at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC;
|
||||
u32 now;
|
||||
|
||||
now = readl(&tc->tc[0].cv) & 0x0000ffff;
|
||||
|
||||
if (now >= gd->lastinc) {
|
||||
/* normal mode */
|
||||
gd->tbl += now - gd->lastinc;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
gd->tbl += now + TIMER_LOAD_VAL - gd->lastinc;
|
||||
}
|
||||
gd->lastinc = now;
|
||||
|
||||
return gd->tbl;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
return get_timer_raw()/TIMER_LOAD_VAL;
|
||||
}
|
||||
|
||||
void udelay_masked(unsigned long usec)
|
||||
{
|
||||
u32 tmo;
|
||||
u32 endtime;
|
||||
signed long diff;
|
||||
|
||||
tmo = CONFIG_SYS_HZ_CLOCK / 1000;
|
||||
tmo *= usec;
|
||||
tmo /= 1000;
|
||||
|
||||
endtime = get_timer_raw() + tmo;
|
||||
|
||||
do {
|
||||
u32 now = get_timer_raw();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@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-common -ffixed-r8 -msoft-float
|
||||
|
||||
PLATFORM_CPPFLAGS += -march=armv4
|
||||
# =========================================================================
|
||||
#
|
||||
# Supply options according to compiler version
|
||||
#
|
||||
# =========================================================================
|
||||
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
|
||||
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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 <asm/system.h>
|
||||
|
||||
static void cache_flush(void);
|
||||
|
||||
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();
|
||||
/* flush I/D-cache */
|
||||
cache_flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* flush I/D-cache */
|
||||
static void cache_flush (void)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
|
||||
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# Cirrus Logic EP93xx CPU-specific Makefile
|
||||
#
|
||||
# Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
|
||||
#
|
||||
# Copyright (C) 2004, 2005
|
||||
# Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
|
||||
#
|
||||
# Copyright (C) 2006
|
||||
# Dominic Rath <Dominic.Rath@gmx.de>
|
||||
#
|
||||
# Based on an original Makefile, which is
|
||||
#
|
||||
# (C) Copyright 2000, 2001, 2002
|
||||
# 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.,
|
||||
# 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
COBJS = cpu.o led.o speed.o timer.o
|
||||
SOBJS = lowlevel_init.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Cirrus Logic EP93xx CPU-specific support.
|
||||
*
|
||||
* Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
|
||||
*
|
||||
* Copyright (C) 2004, 2005
|
||||
* Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.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.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/ep93xx.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* We reset the CPU by generating a 1-->0 transition on DeviceCfg bit 31. */
|
||||
extern void reset_cpu(ulong addr)
|
||||
{
|
||||
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
|
||||
uint32_t value;
|
||||
|
||||
/* Unlock DeviceCfg and set SWRST */
|
||||
writel(0xAA, &syscon->sysswlock);
|
||||
value = readl(&syscon->devicecfg);
|
||||
value |= SYSCON_DEVICECFG_SWRST;
|
||||
writel(value, &syscon->devicecfg);
|
||||
|
||||
/* Unlock DeviceCfg and clear SWRST */
|
||||
writel(0xAA, &syscon->sysswlock);
|
||||
value = readl(&syscon->devicecfg);
|
||||
value &= ~SYSCON_DEVICECFG_SWRST;
|
||||
writel(value, &syscon->devicecfg);
|
||||
|
||||
/* Dying... */
|
||||
while (1)
|
||||
; /* noop */
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2010, 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
|
||||
*
|
||||
* 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 <asm/io.h>
|
||||
#include <asm/arch/ep93xx.h>
|
||||
#include <config.h>
|
||||
#include <status_led.h>
|
||||
|
||||
static uint8_t saved_state[2] = {STATUS_LED_OFF, STATUS_LED_OFF};
|
||||
static uint32_t gpio_pin[2] = {1 << STATUS_LED_GREEN,
|
||||
1 << STATUS_LED_RED};
|
||||
|
||||
inline void switch_LED_on(uint8_t led)
|
||||
{
|
||||
register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE;
|
||||
|
||||
writel(readl(&gpio->pedr) | gpio_pin[led], &gpio->pedr);
|
||||
saved_state[led] = STATUS_LED_ON;
|
||||
}
|
||||
|
||||
inline void switch_LED_off(uint8_t led)
|
||||
{
|
||||
register struct gpio_regs *gpio = (struct gpio_regs *)GPIO_BASE;
|
||||
|
||||
writel(readl(&gpio->pedr) & ~gpio_pin[led], &gpio->pedr);
|
||||
saved_state[led] = STATUS_LED_OFF;
|
||||
}
|
||||
|
||||
void red_led_on(void)
|
||||
{
|
||||
switch_LED_on(STATUS_LED_RED);
|
||||
}
|
||||
|
||||
void red_led_off(void)
|
||||
{
|
||||
switch_LED_off(STATUS_LED_RED);
|
||||
}
|
||||
|
||||
void green_led_on(void)
|
||||
{
|
||||
switch_LED_on(STATUS_LED_GREEN);
|
||||
}
|
||||
|
||||
void green_led_off(void)
|
||||
{
|
||||
switch_LED_off(STATUS_LED_GREEN);
|
||||
}
|
||||
|
||||
void __led_init(led_id_t mask, int state)
|
||||
{
|
||||
__led_set(mask, state);
|
||||
}
|
||||
|
||||
void __led_toggle(led_id_t mask)
|
||||
{
|
||||
if (STATUS_LED_RED == mask) {
|
||||
if (STATUS_LED_ON == saved_state[STATUS_LED_RED])
|
||||
red_led_off();
|
||||
else
|
||||
red_led_on();
|
||||
} else if (STATUS_LED_GREEN == mask) {
|
||||
if (STATUS_LED_ON == saved_state[STATUS_LED_GREEN])
|
||||
green_led_off();
|
||||
else
|
||||
green_led_on();
|
||||
}
|
||||
}
|
||||
|
||||
void __led_set(led_id_t mask, int state)
|
||||
{
|
||||
if (STATUS_LED_RED == mask) {
|
||||
if (STATUS_LED_ON == state)
|
||||
red_led_on();
|
||||
else
|
||||
red_led_off();
|
||||
} else if (STATUS_LED_GREEN == mask) {
|
||||
if (STATUS_LED_ON == state)
|
||||
green_led_on();
|
||||
else
|
||||
green_led_off();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Low-level initialization for EP93xx
|
||||
*
|
||||
* Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
|
||||
*
|
||||
* Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.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 <version.h>
|
||||
#include <asm/arch/ep93xx.h>
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
/* backup return address */
|
||||
ldr r1, =SYSCON_SCRATCH0
|
||||
str lr, [r1]
|
||||
|
||||
/* Turn on both LEDs */
|
||||
bl red_led_on
|
||||
bl green_led_on
|
||||
|
||||
/* Configure flash wait states before we switch to the PLL */
|
||||
bl flash_cfg
|
||||
|
||||
/* Set up PLL */
|
||||
bl pll_cfg
|
||||
|
||||
/* Turn off the Green LED and leave the Red LED on */
|
||||
bl green_led_off
|
||||
|
||||
/* Setup SDRAM */
|
||||
bl sdram_cfg
|
||||
|
||||
/* Turn on Green LED, Turn off the Red LED */
|
||||
bl green_led_on
|
||||
bl red_led_off
|
||||
|
||||
/* FIXME: we use async mode for now */
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
orr r0, r0, #0xc0000000
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/* restore return address */
|
||||
ldr r1, =SYSCON_SCRATCH0
|
||||
ldr lr, [r1]
|
||||
|
||||
mov pc, lr
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Cirrus Logic EP93xx PLL support.
|
||||
*
|
||||
* Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
|
||||
*
|
||||
* 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.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/ep93xx.h>
|
||||
#include <asm/io.h>
|
||||
#include <div64.h>
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* return the PLL output frequency
|
||||
*
|
||||
* PLL rate = CONFIG_SYS_CLK_FREQ * (X1FBD + 1) * (X2FBD + 1)
|
||||
* / (X2IPD + 1) / 2^PS
|
||||
*/
|
||||
static ulong get_PLLCLK(uint32_t *pllreg)
|
||||
{
|
||||
uint8_t i;
|
||||
const uint32_t clkset = readl(pllreg);
|
||||
uint64_t rate = CONFIG_SYS_CLK_FREQ;
|
||||
rate *= ((clkset >> SYSCON_CLKSET_PLL_X1FBD1_SHIFT) & 0x1f) + 1;
|
||||
rate *= ((clkset >> SYSCON_CLKSET_PLL_X2FBD2_SHIFT) & 0x3f) + 1;
|
||||
do_div(rate, (clkset & 0x1f) + 1); /* X2IPD */
|
||||
for (i = 0; i < ((clkset >> SYSCON_CLKSET_PLL_PS_SHIFT) & 3); i++)
|
||||
rate >>= 1;
|
||||
|
||||
return (ulong)rate;
|
||||
}
|
||||
|
||||
/* return FCLK frequency */
|
||||
ulong get_FCLK()
|
||||
{
|
||||
const uint8_t fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
|
||||
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
|
||||
|
||||
const uint32_t clkset1 = readl(&syscon->clkset1);
|
||||
const uint8_t fclk_div =
|
||||
fclk_divisors[(clkset1 >> SYSCON_CLKSET1_FCLK_DIV_SHIFT) & 7];
|
||||
const ulong fclk_rate = get_PLLCLK(&syscon->clkset1) / fclk_div;
|
||||
|
||||
return fclk_rate;
|
||||
}
|
||||
|
||||
/* return HCLK frequency */
|
||||
ulong get_HCLK(void)
|
||||
{
|
||||
const uint8_t hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
|
||||
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
|
||||
|
||||
const uint32_t clkset1 = readl(&syscon->clkset1);
|
||||
const uint8_t hclk_div =
|
||||
hclk_divisors[(clkset1 >> SYSCON_CLKSET1_HCLK_DIV_SHIFT) & 7];
|
||||
const ulong hclk_rate = get_PLLCLK(&syscon->clkset1) / hclk_div;
|
||||
|
||||
return hclk_rate;
|
||||
}
|
||||
|
||||
/* return PCLK frequency */
|
||||
ulong get_PCLK(void)
|
||||
{
|
||||
const uint8_t pclk_divisors[] = { 1, 2, 4, 8 };
|
||||
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
|
||||
|
||||
const uint32_t clkset1 = readl(&syscon->clkset1);
|
||||
const uint8_t pclk_div =
|
||||
pclk_divisors[(clkset1 >> SYSCON_CLKSET1_PCLK_DIV_SHIFT) & 3];
|
||||
const ulong pclk_rate = get_HCLK() / pclk_div;
|
||||
|
||||
return pclk_rate;
|
||||
}
|
||||
|
||||
/* return UCLK frequency */
|
||||
ulong get_UCLK(void)
|
||||
{
|
||||
struct syscon_regs *syscon = (struct syscon_regs *)SYSCON_BASE;
|
||||
ulong uclk_rate;
|
||||
|
||||
const uint32_t value = readl(&syscon->pwrcnt);
|
||||
if (value & SYSCON_PWRCNT_UART_BAUD)
|
||||
uclk_rate = CONFIG_SYS_CLK_FREQ;
|
||||
else
|
||||
uclk_rate = CONFIG_SYS_CLK_FREQ / 2;
|
||||
|
||||
return uclk_rate;
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Cirrus Logic EP93xx timer support.
|
||||
*
|
||||
* Copyright (C) 2009, 2010 Matthias Kaehlcke <matthias@kaehlcke.net>
|
||||
*
|
||||
* Copyright (C) 2004, 2005
|
||||
* Cory T. Tusar, Videon Central, Inc., <ctusar@videon-central.com>
|
||||
*
|
||||
* Based on the original intr.c Cirrus Logic EP93xx Rev D. interrupt support,
|
||||
* author unknown.
|
||||
*
|
||||
* 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.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/arch/ep93xx.h>
|
||||
#include <asm/io.h>
|
||||
#include <div64.h>
|
||||
|
||||
#define TIMER_CLKSEL (1 << 3)
|
||||
#define TIMER_ENABLE (1 << 7)
|
||||
|
||||
#define TIMER_FREQ 508469 /* ticks / second */
|
||||
#define TIMER_MAX_VAL 0xFFFFFFFF
|
||||
|
||||
static struct ep93xx_timer
|
||||
{
|
||||
unsigned long long ticks;
|
||||
unsigned long last_read;
|
||||
} timer;
|
||||
|
||||
static inline unsigned long long usecs_to_ticks(unsigned long usecs)
|
||||
{
|
||||
unsigned long long ticks = (unsigned long long)usecs * TIMER_FREQ;
|
||||
do_div(ticks, 1000 * 1000);
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static inline void read_timer(void)
|
||||
{
|
||||
struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE;
|
||||
const unsigned long now = TIMER_MAX_VAL - readl(&timer_regs->timer3.value);
|
||||
|
||||
if (now >= timer.last_read)
|
||||
timer.ticks += now - timer.last_read;
|
||||
else
|
||||
/* an overflow occurred */
|
||||
timer.ticks += TIMER_MAX_VAL - timer.last_read + now;
|
||||
|
||||
timer.last_read = now;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the number of ticks (in CONFIG_SYS_HZ resolution)
|
||||
*/
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
unsigned long long sys_ticks;
|
||||
|
||||
read_timer();
|
||||
|
||||
sys_ticks = timer.ticks * CONFIG_SYS_HZ;
|
||||
do_div(sys_ticks, TIMER_FREQ);
|
||||
|
||||
return sys_ticks;
|
||||
}
|
||||
|
||||
unsigned long get_timer_masked(void)
|
||||
{
|
||||
return get_ticks();
|
||||
}
|
||||
|
||||
unsigned long get_timer(unsigned long base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
unsigned long long target;
|
||||
|
||||
read_timer();
|
||||
|
||||
target = timer.ticks + usecs_to_ticks(usec);
|
||||
|
||||
while (timer.ticks < target)
|
||||
read_timer();
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
struct timer_regs *timer_regs = (struct timer_regs *)TIMER_BASE;
|
||||
|
||||
/* use timer 3 with 508KHz and free running, not enabled now */
|
||||
writel(TIMER_CLKSEL, &timer_regs->timer3.control);
|
||||
|
||||
/* set initial timer value */
|
||||
writel(TIMER_MAX_VAL, &timer_regs->timer3.load);
|
||||
|
||||
/* Enable the timer */
|
||||
writel(TIMER_ENABLE | TIMER_CLKSEL,
|
||||
&timer_regs->timer3.control);
|
||||
|
||||
/* Reset the timer */
|
||||
read_timer();
|
||||
timer.ticks = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is derived from PowerPC code (timebase clock frequency).
|
||||
* On ARM it returns the number of timer ticks per second.
|
||||
*/
|
||||
unsigned long get_tbclk(void)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* (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
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
arch/arm/cpu/arm920t/start.o (.text)
|
||||
/* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */
|
||||
. = 0x1000;
|
||||
LONG(0x53555243)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
__bss_end__ = .;
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
|
@ -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$(SOC).o
|
||||
|
||||
COBJS += generic.o
|
||||
COBJS += speed.o
|
||||
COBJS += timer.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* arch/arm/mach-imx/generic.c
|
||||
*
|
||||
* author: Sascha Hauer
|
||||
* Created: april 20th, 2004
|
||||
* Copyright: Synertronixx GmbH
|
||||
*
|
||||
* Common code for i.MX machines
|
||||
*
|
||||
* 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>
|
||||
|
||||
#ifdef CONFIG_IMX
|
||||
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
void imx_gpio_mode(int gpio_mode)
|
||||
{
|
||||
unsigned int pin = gpio_mode & GPIO_PIN_MASK;
|
||||
unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> 5;
|
||||
unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> 10;
|
||||
unsigned int tmp;
|
||||
|
||||
/* Pullup enable */
|
||||
if(gpio_mode & GPIO_PUEN)
|
||||
PUEN(port) |= (1<<pin);
|
||||
else
|
||||
PUEN(port) &= ~(1<<pin);
|
||||
|
||||
/* Data direction */
|
||||
if(gpio_mode & GPIO_OUT)
|
||||
DDIR(port) |= 1<<pin;
|
||||
else
|
||||
DDIR(port) &= ~(1<<pin);
|
||||
|
||||
/* Primary / alternate function */
|
||||
if(gpio_mode & GPIO_AF)
|
||||
GPR(port) |= (1<<pin);
|
||||
else
|
||||
GPR(port) &= ~(1<<pin);
|
||||
|
||||
/* use as gpio? */
|
||||
if( ocr == 3 )
|
||||
GIUS(port) |= (1<<pin);
|
||||
else
|
||||
GIUS(port) &= ~(1<<pin);
|
||||
|
||||
/* Output / input configuration */
|
||||
/* FIXME: I'm not very sure about OCR and ICONF, someone
|
||||
* should have a look over it
|
||||
*/
|
||||
if(pin<16) {
|
||||
tmp = OCR1(port);
|
||||
tmp &= ~( 3<<(pin*2));
|
||||
tmp |= (ocr << (pin*2));
|
||||
OCR1(port) = tmp;
|
||||
|
||||
if( gpio_mode & GPIO_AOUT )
|
||||
ICONFA1(port) &= ~( 3<<(pin*2));
|
||||
if( gpio_mode & GPIO_BOUT )
|
||||
ICONFB1(port) &= ~( 3<<(pin*2));
|
||||
} else {
|
||||
tmp = OCR2(port);
|
||||
tmp &= ~( 3<<((pin-16)*2));
|
||||
tmp |= (ocr << ((pin-16)*2));
|
||||
OCR2(port) = tmp;
|
||||
|
||||
if( gpio_mode & GPIO_AOUT )
|
||||
ICONFA2(port) &= ~( 3<<((pin-16)*2));
|
||||
if( gpio_mode & GPIO_BOUT )
|
||||
ICONFB2(port) &= ~( 3<<((pin-16)*2));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IMX */
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
*
|
||||
* (c) 2004 Sascha Hauer <sascha@saschahauer.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>
|
||||
#if defined (CONFIG_IMX)
|
||||
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* NOTE: This describes the proper use of this file.
|
||||
*
|
||||
* CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
|
||||
* SH FIXME: 16780000 in our case
|
||||
* get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
|
||||
* the specified bus in HZ.
|
||||
*/
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
ulong get_systemPLLCLK(void)
|
||||
{
|
||||
/* FIXME: We assume System_SEL = 0 here */
|
||||
u32 spctl0 = SPCTL0;
|
||||
u32 mfi = (spctl0 >> 10) & 0xf;
|
||||
u32 mfn = spctl0 & 0x3f;
|
||||
u32 mfd = (spctl0 >> 16) & 0x3f;
|
||||
u32 pd = (spctl0 >> 26) & 0xf;
|
||||
|
||||
mfi = mfi<=5 ? 5 : mfi;
|
||||
|
||||
return (2*(CONFIG_SYSPLL_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
|
||||
}
|
||||
|
||||
ulong get_mcuPLLCLK(void)
|
||||
{
|
||||
/* FIXME: We assume System_SEL = 0 here */
|
||||
u32 mpctl0 = MPCTL0;
|
||||
u32 mfi = (mpctl0 >> 10) & 0xf;
|
||||
u32 mfn = mpctl0 & 0x3f;
|
||||
u32 mfd = (mpctl0 >> 16) & 0x3f;
|
||||
u32 pd = (mpctl0 >> 26) & 0xf;
|
||||
|
||||
mfi = mfi<=5 ? 5 : mfi;
|
||||
|
||||
return (2*(CONFIG_SYS_CLK_FREQ>>10)*( (mfi<<10) + (mfn<<10)/(mfd+1)))/(pd+1);
|
||||
}
|
||||
|
||||
ulong get_FCLK(void)
|
||||
{
|
||||
return (( CSCR>>15)&1) ? get_mcuPLLCLK()>>1 : get_mcuPLLCLK();
|
||||
}
|
||||
|
||||
/* return HCLK frequency */
|
||||
ulong get_HCLK(void)
|
||||
{
|
||||
u32 bclkdiv = (( CSCR >> 10 ) & 0xf) + 1;
|
||||
printf("bclkdiv: %d\n", bclkdiv);
|
||||
return get_systemPLLCLK() / bclkdiv;
|
||||
}
|
||||
|
||||
/* return BCLK frequency */
|
||||
ulong get_BCLK(void)
|
||||
{
|
||||
return get_HCLK();
|
||||
}
|
||||
|
||||
ulong get_PERCLK1(void)
|
||||
{
|
||||
return get_systemPLLCLK() / (((PCDR) & 0xf)+1);
|
||||
}
|
||||
|
||||
ulong get_PERCLK2(void)
|
||||
{
|
||||
return get_systemPLLCLK() / (((PCDR>>4) & 0xf)+1);
|
||||
}
|
||||
|
||||
ulong get_PERCLK3(void)
|
||||
{
|
||||
return get_systemPLLCLK() / (((PCDR>>16) & 0x7f)+1);
|
||||
}
|
||||
|
||||
#endif /* defined (CONFIG_IMX) */
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* (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
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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>
|
||||
#if defined (CONFIG_IMX)
|
||||
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
int timer_init (void)
|
||||
{
|
||||
int i;
|
||||
/* setup GP Timer 1 */
|
||||
TCTL1 = TCTL_SWR;
|
||||
for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */
|
||||
TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */
|
||||
TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */
|
||||
|
||||
/* Reset the timer */
|
||||
TCTL1 &= ~TCTL_TEN;
|
||||
TCTL1 |= TCTL_TEN; /* Enable timer */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
ulong get_timer (ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
ulong get_timer_masked (void)
|
||||
{
|
||||
return TCN1;
|
||||
}
|
||||
|
||||
void udelay_masked (unsigned long usec)
|
||||
{
|
||||
ulong endtime = get_timer_masked() + usec;
|
||||
signed long diff;
|
||||
|
||||
do {
|
||||
ulong now = get_timer_masked ();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
void __udelay (unsigned long usec)
|
||||
{
|
||||
udelay_masked(usec);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
ulong tbclk;
|
||||
|
||||
tbclk = CONFIG_SYS_HZ;
|
||||
|
||||
return tbclk;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the cpu by setting up the watchdog timer and let him time out
|
||||
*/
|
||||
void reset_cpu (ulong ignored)
|
||||
{
|
||||
/* Disable watchdog and set Time-Out field to 0 */
|
||||
WCR = 0x00000000;
|
||||
|
||||
/* Write Service Sequence */
|
||||
WSR = 0x00005555;
|
||||
WSR = 0x0000AAAA;
|
||||
|
||||
/* Enable watchdog */
|
||||
WCR = 0x00000001;
|
||||
|
||||
while (1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
#endif /* defined (CONFIG_IMX) */
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* (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
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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>
|
||||
|
||||
#if defined (CONFIG_ARCH_INTEGRATOR)
|
||||
void do_irq (struct pt_regs *pt_regs)
|
||||
{
|
||||
/* ASSUMED to be a timer interrupt */
|
||||
/* Just clear it - count handled in */
|
||||
/* integratorap.c */
|
||||
*(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0x0C) = 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -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$(SOC).o
|
||||
|
||||
SOBJS = lowlevel_init.o
|
||||
|
||||
COBJS = timer.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* lowlevel_init.S - basic hardware initialization for the KS8695 CPU
|
||||
*
|
||||
* Copyright (c) 2004-2005, Greg Ungerer <greg.ungerer@opengear.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 <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/arch/platform.h>
|
||||
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Handy dandy macros
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
/* Delay a bit */
|
||||
.macro DELAY_FOR cycles, reg0
|
||||
ldr \reg0, =\cycles
|
||||
subs \reg0, \reg0, #1
|
||||
subne pc, pc, #0xc
|
||||
.endm
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Some local storage.
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
/* Should we boot with an interactive console or not */
|
||||
.globl serial_console
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Raw hardware initialization code. The important thing is to get
|
||||
* SDRAM setup and running. We do some other basic things here too,
|
||||
* like getting the PLL set for high speed, and init the LEDs.
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
|
||||
#if DEBUG
|
||||
/*
|
||||
* enable UART for early debug trace
|
||||
*/
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_UART_DIVISOR)
|
||||
mov r2, #0xd9
|
||||
str r2, [r1] /* 115200 baud */
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_UART_LINE_CTRL)
|
||||
mov r2, #0x03
|
||||
str r2, [r1] /* 8 data bits, no parity, 1 stop */
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING)
|
||||
mov r2, #0x41
|
||||
str r2, [r1] /* write 'A' */
|
||||
#endif
|
||||
#if DEBUG
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING)
|
||||
mov r2, #0x42
|
||||
str r2, [r1]
|
||||
#endif
|
||||
|
||||
/*
|
||||
* remap the memory and flash regions. we want to end up with
|
||||
* ram from address 0, and flash at 32MB.
|
||||
*/
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL0)
|
||||
ldr r2, =0xbfc00040
|
||||
str r2, [r1] /* large flash map */
|
||||
ldr pc, =(highflash+0x02000000-0x00f00000) /* jump to high flash address */
|
||||
highflash:
|
||||
ldr r2, =0x8fe00040
|
||||
str r2, [r1] /* remap flash range */
|
||||
|
||||
/*
|
||||
* remap the second select region to the 4MB immediately after
|
||||
* the first region. This way if you have a larger flash (say 8Mb)
|
||||
* then you can have it all mapped nicely. Has no effect if you
|
||||
* only have a 4Mb or smaller flash.
|
||||
*/
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL1)
|
||||
ldr r2, =0x9fe40040
|
||||
str r2, [r1] /* remap flash2 region, contiguous */
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL)
|
||||
ldr r2, =0x30000005
|
||||
str r2, [r1] /* enable both flash selects */
|
||||
|
||||
#ifdef CONFIG_CM41xx
|
||||
/*
|
||||
* map the second flash chip, using the external IO lines.
|
||||
*/
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL0)
|
||||
ldr r2, =0xafe80b6d
|
||||
str r2, [r1] /* remap io0 region, contiguous */
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_IO_CTRL1)
|
||||
ldr r2, =0xbfec0b6d
|
||||
str r2, [r1] /* remap io1 region, contiguous */
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL)
|
||||
ldr r2, =0x30050005
|
||||
str r2, [r1] /* enable second flash */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* before relocating, we have to setup RAM timing
|
||||
*/
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL0)
|
||||
#if (PHYS_SDRAM_1_SIZE == 0x02000000)
|
||||
ldr r2, =0x7fc0000e /* 32MB */
|
||||
#else
|
||||
ldr r2, =0x3fc0000e /* 16MB */
|
||||
#endif
|
||||
str r2, [r1] /* configure sdram bank0 setup */
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL1)
|
||||
mov r2, #0
|
||||
str r2, [r1] /* configure sdram bank1 setup */
|
||||
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_GENERAL)
|
||||
ldr r2, =0x0000000a
|
||||
str r2, [r1] /* set RAS/CAS timing */
|
||||
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER)
|
||||
ldr r2, =0x00030000
|
||||
str r2, [r1] /* send NOP command */
|
||||
DELAY_FOR 0x100, r0
|
||||
ldr r2, =0x00010000
|
||||
str r2, [r1] /* send PRECHARGE-ALL */
|
||||
DELAY_FOR 0x100, r0
|
||||
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_REFRESH)
|
||||
ldr r2, =0x00000020
|
||||
str r2, [r1] /* set for fast refresh */
|
||||
DELAY_FOR 0x100, r0
|
||||
ldr r2, =0x00000190
|
||||
str r2, [r1] /* set normal refresh timing */
|
||||
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER)
|
||||
ldr r2, =0x00020033
|
||||
str r2, [r1] /* send mode command */
|
||||
DELAY_FOR 0x100, r0
|
||||
ldr r2, =0x01f00000
|
||||
str r2, [r1] /* enable sdram fifos */
|
||||
|
||||
/*
|
||||
* set pll to top speed
|
||||
*/
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SYSTEN_BUS_CLOCK)
|
||||
mov r2, #0
|
||||
str r2, [r1] /* set pll clock to 166MHz */
|
||||
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_SWITCH_CTRL0)
|
||||
ldr r2, [r1] /* Get switch ctrl0 register */
|
||||
and r2, r2, #0x0fc00000 /* Mask out LED control bits */
|
||||
orr r2, r2, #0x01800000 /* Set Link/activity/speed actions */
|
||||
str r2, [r1]
|
||||
|
||||
#ifdef CONFIG_CM4008
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_MODE)
|
||||
ldr r2, =0x0000fe30
|
||||
str r2, [r1] /* enable LED's as outputs */
|
||||
ldr r1, =(KS8695_IO_BASE+KS8695_GPIO_DATA)
|
||||
ldr r2, =0x0000fe20
|
||||
str r2, [r1] /* turn on power LED */
|
||||
#endif
|
||||
#if defined(CONFIG_CM4008) || defined(CONFIG_CM41xx)
|
||||
ldr r2, [r1] /* get current GPIO input data */
|
||||
tst r2, #0x8 /* check if "erase" depressed */
|
||||
beq nobutton
|
||||
mov r2, #0 /* be quiet on boot, no console */
|
||||
ldr r1, =serial_console
|
||||
str r2, [r1]
|
||||
nobutton:
|
||||
#endif
|
||||
|
||||
add lr, lr, #0x02000000 /* flash is now mapped high */
|
||||
add ip, ip, #0x02000000 /* this is a hack */
|
||||
mov pc, lr /* all done, return */
|
||||
|
||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.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/arch/platform.h>
|
||||
|
||||
/*
|
||||
* Initial timer set constants. Nothing complicated, just set for a 1ms
|
||||
* tick.
|
||||
*/
|
||||
#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_1)
|
||||
#define TIMER_COUNT (TIMER_INTERVAL / 2)
|
||||
#define TIMER_PULSE TIMER_COUNT
|
||||
|
||||
/*
|
||||
* Handy KS8695 register access functions.
|
||||
*/
|
||||
#define ks8695_read(a) *((volatile ulong *) (KS8695_IO_BASE + (a)))
|
||||
#define ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v)
|
||||
|
||||
ulong timer_ticks;
|
||||
|
||||
int timer_init (void)
|
||||
{
|
||||
/* Set the hadware timer for 1ms */
|
||||
ks8695_write(KS8695_TIMER1, TIMER_COUNT);
|
||||
ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE);
|
||||
ks8695_write(KS8695_TIMER_CTRL, 0x2);
|
||||
timer_ticks = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
/* Check for timer wrap */
|
||||
if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) {
|
||||
/* Clear interrupt condition */
|
||||
ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1);
|
||||
timer_ticks++;
|
||||
}
|
||||
return timer_ticks;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return (get_timer_masked() - base);
|
||||
}
|
||||
|
||||
void __udelay(ulong usec)
|
||||
{
|
||||
ulong start = get_timer_masked();
|
||||
ulong end;
|
||||
|
||||
/* Only 1ms resolution :-( */
|
||||
end = usec / 1000;
|
||||
while (get_timer(start) < end)
|
||||
;
|
||||
}
|
||||
|
||||
void reset_cpu (ulong ignored)
|
||||
{
|
||||
ulong tc;
|
||||
|
||||
/* Set timer0 to watchdog, and let it timeout */
|
||||
tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2;
|
||||
ks8695_write(KS8695_TIMER_CTRL, tc);
|
||||
ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff));
|
||||
ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1));
|
||||
|
||||
/* Should only wait here till watchdog resets */
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
# (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$(SOC).o
|
||||
|
||||
COBJS-$(CONFIG_USE_IRQ) += interrupts.o
|
||||
COBJS-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o
|
||||
COBJS-y += speed.o
|
||||
COBJS-y += timer.o
|
||||
COBJS-y += usb.o
|
||||
COBJS-y += usb_ohci.o
|
||||
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* (C) Copyright 2010
|
||||
* David Mueller <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
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/s3c24x0_cpu.h>
|
||||
|
||||
typedef ulong (*getfreq)(void);
|
||||
|
||||
static const getfreq freq_f[] = {
|
||||
get_FCLK,
|
||||
get_HCLK,
|
||||
get_PCLK,
|
||||
};
|
||||
|
||||
static const char freq_c[] = { 'F', 'H', 'P' };
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
int i;
|
||||
char buf[32];
|
||||
/* the S3C2400 seems to be lacking a CHIP ID register */
|
||||
#ifndef CONFIG_S3C2400
|
||||
ulong cpuid;
|
||||
struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
|
||||
|
||||
cpuid = readl(&gpio->gstatus1);
|
||||
printf("CPUID: %8lX\n", cpuid);
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(freq_f); i++)
|
||||
printf("%cCLK: %8s MHz\n", freq_c[i], strmhz(buf, freq_f[i]()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* (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
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <asm/arch/s3c24x0_cpu.h>
|
||||
#include <asm/proc-armv/ptrace.h>
|
||||
|
||||
void do_irq (struct pt_regs *pt_regs)
|
||||
{
|
||||
struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt();
|
||||
u_int32_t intpnd = readl(&irq->INTPND);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* (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>
|
||||
#ifdef CONFIG_S3C24X0
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/s3c24x0_cpu.h>
|
||||
|
||||
#define MPLL 0
|
||||
#define UPLL 1
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* 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)
|
||||
{
|
||||
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
|
||||
ulong r, m, p, s;
|
||||
|
||||
if (pllreg == MPLL)
|
||||
r = readl(&clk_power->mpllcon);
|
||||
else if (pllreg == UPLL)
|
||||
r = readl(&clk_power->upllcon);
|
||||
else
|
||||
hang();
|
||||
|
||||
m = ((r & 0xFF000) >> 12) + 8;
|
||||
p = ((r & 0x003F0) >> 4) + 2;
|
||||
s = r & 0x3;
|
||||
|
||||
#if defined(CONFIG_S3C2440)
|
||||
if (pllreg == MPLL)
|
||||
return 2 * m * (CONFIG_SYS_CLK_FREQ / (p << s));
|
||||
#endif
|
||||
return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
|
||||
|
||||
}
|
||||
|
||||
/* return FCLK frequency */
|
||||
ulong get_FCLK(void)
|
||||
{
|
||||
return get_PLLCLK(MPLL);
|
||||
}
|
||||
|
||||
/* return HCLK frequency */
|
||||
ulong get_HCLK(void)
|
||||
{
|
||||
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
|
||||
#ifdef CONFIG_S3C2440
|
||||
switch (readl(&clk_power->clkdivn) & 0x6) {
|
||||
default:
|
||||
case 0:
|
||||
return get_FCLK();
|
||||
case 2:
|
||||
return get_FCLK() / 2;
|
||||
case 4:
|
||||
return (readl(&clk_power->camdivn) & (1 << 9)) ?
|
||||
get_FCLK() / 8 : get_FCLK() / 4;
|
||||
case 6:
|
||||
return (readl(&clk_power->camdivn) & (1 << 8)) ?
|
||||
get_FCLK() / 6 : get_FCLK() / 3;
|
||||
}
|
||||
#else
|
||||
return (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* return PCLK frequency */
|
||||
ulong get_PCLK(void)
|
||||
{
|
||||
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
|
||||
|
||||
return (readl(&clk_power->clkdivn) & 1) ? get_HCLK() / 2 : get_HCLK();
|
||||
}
|
||||
|
||||
/* return UCLK frequency */
|
||||
ulong get_UCLK(void)
|
||||
{
|
||||
return get_PLLCLK(UPLL);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_S3C24X0 */
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* (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
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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>
|
||||
#ifdef CONFIG_S3C24X0
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/s3c24x0_cpu.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
|
||||
ulong tmr;
|
||||
|
||||
/* use PWM Timer 4 because it has no output */
|
||||
/* prescaler for Timer 4 is 16 */
|
||||
writel(0x0f00, &timers->tcfg0);
|
||||
if (gd->tbu == 0) {
|
||||
/*
|
||||
* for 10 ms clock period @ PCLK with 4 bit divider = 1/2
|
||||
* (default) and prescaler = 16. Should be 10390
|
||||
* @33.25MHz and 15625 @ 50 MHz
|
||||
*/
|
||||
gd->tbu = get_PCLK() / (2 * 16 * 100);
|
||||
gd->timer_rate_hz = get_PCLK() / (2 * 16);
|
||||
}
|
||||
/* load value for 10 ms timeout */
|
||||
writel(gd->tbu, &timers->tcntb4);
|
||||
/* auto load, manual update of timer 4 */
|
||||
tmr = (readl(&timers->tcon) & ~0x0700000) | 0x0600000;
|
||||
writel(tmr, &timers->tcon);
|
||||
/* auto load, start timer 4 */
|
||||
tmr = (tmr & ~0x0700000) | 0x0500000;
|
||||
writel(tmr, &timers->tcon);
|
||||
gd->lastinc = 0;
|
||||
gd->tbl = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
void __udelay (unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
ulong start = get_ticks();
|
||||
|
||||
tmo = usec / 1000;
|
||||
tmo *= (gd->tbu * 100);
|
||||
tmo /= 1000;
|
||||
|
||||
while ((ulong) (get_ticks() - start) < tmo)
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
ulong tmr = get_ticks();
|
||||
|
||||
return tmr / (gd->timer_rate_hz / CONFIG_SYS_HZ);
|
||||
}
|
||||
|
||||
void udelay_masked(unsigned long usec)
|
||||
{
|
||||
ulong tmo;
|
||||
ulong endtime;
|
||||
signed long diff;
|
||||
|
||||
if (usec >= 1000) {
|
||||
tmo = usec / 1000;
|
||||
tmo *= (gd->tbu * 100);
|
||||
tmo /= 1000;
|
||||
} else {
|
||||
tmo = usec * (gd->tbu * 100);
|
||||
tmo /= (1000 * 1000);
|
||||
}
|
||||
|
||||
endtime = get_ticks() + tmo;
|
||||
|
||||
do {
|
||||
ulong now = get_ticks();
|
||||
diff = endtime - now;
|
||||
} while (diff >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
|
||||
ulong now = readl(&timers->tcnto4) & 0xffff;
|
||||
|
||||
if (gd->lastinc >= now) {
|
||||
/* normal mode */
|
||||
gd->tbl += gd->lastinc - now;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
gd->tbl += gd->lastinc + gd->tbu - now;
|
||||
}
|
||||
gd->lastinc = now;
|
||||
|
||||
return gd->tbl;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
||||
|
||||
/*
|
||||
* reset the cpu by setting up the watchdog timer and let him time out
|
||||
*/
|
||||
void reset_cpu(ulong ignored)
|
||||
{
|
||||
struct s3c24x0_watchdog *watchdog;
|
||||
|
||||
watchdog = s3c24x0_get_base_watchdog();
|
||||
|
||||
/* Disable watchdog */
|
||||
writel(0x0000, &watchdog->wtcon);
|
||||
|
||||
/* Initialize watchdog timer count register */
|
||||
writel(0x0001, &watchdog->wtcnt);
|
||||
|
||||
/* Enable watchdog timer; assert reset at timer timeout */
|
||||
writel(0x0021, &watchdog->wtcon);
|
||||
|
||||
while (1)
|
||||
/* loop forever and wait for reset to happen */;
|
||||
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
#endif /* CONFIG_S3C24X0 */
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* (C) Copyright 2006
|
||||
* DENX Software Engineering <mk@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>
|
||||
|
||||
#if defined(CONFIG_USB_OHCI_NEW) && \
|
||||
defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \
|
||||
defined(CONFIG_S3C24X0)
|
||||
|
||||
#include <asm/arch/s3c24x0_cpu.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
int usb_cpu_init(void)
|
||||
{
|
||||
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
|
||||
struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
|
||||
|
||||
/*
|
||||
* Set the 48 MHz UPLL clocking. Values are taken from
|
||||
* "PLL value selection guide", 6-23, s3c2400_UM.pdf.
|
||||
*/
|
||||
writel((40 << 12) + (1 << 4) + 2, &clk_power->upllcon);
|
||||
/* 1 = use pads related USB for USB host */
|
||||
writel(readl(&gpio->misccr) | 0x8, &gpio->misccr);
|
||||
|
||||
/*
|
||||
* Enable USB host clock.
|
||||
*/
|
||||
writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_cpu_stop(void)
|
||||
{
|
||||
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
|
||||
/* may not want to do this */
|
||||
writel(readl(&clk_power->clkcon) & ~(1 << 4), &clk_power->clkcon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_cpu_init_fail(void)
|
||||
{
|
||||
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
|
||||
writel(readl(&clk_power->clkcon) & ~(1 << 4), &clk_power->clkcon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_USB_OHCI_NEW) && \
|
||||
defined(CONFIG_SYS_USB_OHCI_CPU_INIT) && \
|
||||
defined(CONFIG_S3C24X0) */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* URB OHCI HCD (Host Controller Driver) for USB.
|
||||
*
|
||||
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
|
||||
* (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
|
||||
*
|
||||
* usb-ohci.h
|
||||
*/
|
||||
|
||||
|
||||
static int cc_to_error[16] = {
|
||||
|
||||
/* mapping of the OHCI CC status to error codes */
|
||||
/* No Error */ 0,
|
||||
/* CRC Error */ USB_ST_CRC_ERR,
|
||||
/* Bit Stuff */ USB_ST_BIT_ERR,
|
||||
/* Data Togg */ USB_ST_CRC_ERR,
|
||||
/* Stall */ USB_ST_STALLED,
|
||||
/* DevNotResp */ -1,
|
||||
/* PIDCheck */ USB_ST_BIT_ERR,
|
||||
/* UnExpPID */ USB_ST_BIT_ERR,
|
||||
/* DataOver */ USB_ST_BUF_ERR,
|
||||
/* DataUnder */ USB_ST_BUF_ERR,
|
||||
/* reservd */ -1,
|
||||
/* reservd */ -1,
|
||||
/* BufferOver */ USB_ST_BUF_ERR,
|
||||
/* BuffUnder */ USB_ST_BUF_ERR,
|
||||
/* Not Access */ -1,
|
||||
/* Not Access */ -1
|
||||
};
|
||||
|
||||
/* ED States */
|
||||
#define ED_NEW 0x00
|
||||
#define ED_UNLINK 0x01
|
||||
#define ED_OPER 0x02
|
||||
#define ED_DEL 0x04
|
||||
#define ED_URB_DEL 0x08
|
||||
|
||||
/* usb_ohci_ed */
|
||||
struct ed {
|
||||
__u32 hwINFO;
|
||||
__u32 hwTailP;
|
||||
__u32 hwHeadP;
|
||||
__u32 hwNextED;
|
||||
|
||||
struct ed *ed_prev;
|
||||
__u8 int_period;
|
||||
__u8 int_branch;
|
||||
__u8 int_load;
|
||||
__u8 int_interval;
|
||||
__u8 state;
|
||||
__u8 type;
|
||||
__u16 last_iso;
|
||||
struct ed *ed_rm_list;
|
||||
|
||||
struct usb_device *usb_dev;
|
||||
__u32 unused[3];
|
||||
} __attribute__ ((aligned(16)));
|
||||
|
||||
/* TD info field */
|
||||
#define TD_CC 0xf0000000
|
||||
#define TD_CC_GET(td_p) (((td_p) >> 28) & 0x0f)
|
||||
#define TD_CC_SET(td_p, cc) \
|
||||
{(td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)}
|
||||
#define TD_EC 0x0C000000
|
||||
#define TD_T 0x03000000
|
||||
#define TD_T_DATA0 0x02000000
|
||||
#define TD_T_DATA1 0x03000000
|
||||
#define TD_T_TOGGLE 0x00000000
|
||||
#define TD_R 0x00040000
|
||||
#define TD_DI 0x00E00000
|
||||
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
|
||||
#define TD_DP 0x00180000
|
||||
#define TD_DP_SETUP 0x00000000
|
||||
#define TD_DP_IN 0x00100000
|
||||
#define TD_DP_OUT 0x00080000
|
||||
|
||||
#define TD_ISO 0x00010000
|
||||
#define TD_DEL 0x00020000
|
||||
|
||||
/* CC Codes */
|
||||
#define TD_CC_NOERROR 0x00
|
||||
#define TD_CC_CRC 0x01
|
||||
#define TD_CC_BITSTUFFING 0x02
|
||||
#define TD_CC_DATATOGGLEM 0x03
|
||||
#define TD_CC_STALL 0x04
|
||||
#define TD_DEVNOTRESP 0x05
|
||||
#define TD_PIDCHECKFAIL 0x06
|
||||
#define TD_UNEXPECTEDPID 0x07
|
||||
#define TD_DATAOVERRUN 0x08
|
||||
#define TD_DATAUNDERRUN 0x09
|
||||
#define TD_BUFFEROVERRUN 0x0C
|
||||
#define TD_BUFFERUNDERRUN 0x0D
|
||||
#define TD_NOTACCESSED 0x0F
|
||||
|
||||
|
||||
#define MAXPSW 1
|
||||
|
||||
struct td {
|
||||
__u32 hwINFO;
|
||||
__u32 hwCBP; /* Current Buffer Pointer */
|
||||
__u32 hwNextTD; /* Next TD Pointer */
|
||||
__u32 hwBE; /* Memory Buffer End Pointer */
|
||||
|
||||
__u8 unused;
|
||||
__u8 index;
|
||||
struct ed *ed;
|
||||
struct td *next_dl_td;
|
||||
struct usb_device *usb_dev;
|
||||
int transfer_len;
|
||||
__u32 data;
|
||||
|
||||
__u32 unused2[2];
|
||||
} __attribute__ ((aligned(32)));
|
||||
|
||||
#define OHCI_ED_SKIP (1 << 14)
|
||||
|
||||
/*
|
||||
* The HCCA (Host Controller Communications Area) is a 256 byte
|
||||
* structure defined in the OHCI spec. that the host controller is
|
||||
* told the base address of. It must be 256-byte aligned.
|
||||
*/
|
||||
|
||||
#define NUM_INTS 32 /* part of the OHCI standard */
|
||||
struct ohci_hcca {
|
||||
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
|
||||
__u16 frame_no; /* current frame number */
|
||||
__u16 pad1; /* set to 0 on each frame_no change */
|
||||
__u32 done_head; /* info returned for an interrupt */
|
||||
u8 reserved_for_hc[116];
|
||||
} __attribute__ ((aligned(256)));
|
||||
|
||||
/*
|
||||
* Maximum number of root hub ports.
|
||||
*/
|
||||
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
|
||||
|
||||
/*
|
||||
* This is the structure of the OHCI controller's memory mapped I/O
|
||||
* region. This is Memory Mapped I/O. You must use the readl() and
|
||||
* writel() macros defined in asm/io.h to access these!!
|
||||
*/
|
||||
struct ohci_regs {
|
||||
/* control and status registers */
|
||||
__u32 revision;
|
||||
__u32 control;
|
||||
__u32 cmdstatus;
|
||||
__u32 intrstatus;
|
||||
__u32 intrenable;
|
||||
__u32 intrdisable;
|
||||
/* memory pointers */
|
||||
__u32 hcca;
|
||||
__u32 ed_periodcurrent;
|
||||
__u32 ed_controlhead;
|
||||
__u32 ed_controlcurrent;
|
||||
__u32 ed_bulkhead;
|
||||
__u32 ed_bulkcurrent;
|
||||
__u32 donehead;
|
||||
/* frame counters */
|
||||
__u32 fminterval;
|
||||
__u32 fmremaining;
|
||||
__u32 fmnumber;
|
||||
__u32 periodicstart;
|
||||
__u32 lsthresh;
|
||||
/* Root hub ports */
|
||||
struct ohci_roothub_regs {
|
||||
__u32 a;
|
||||
__u32 b;
|
||||
__u32 status;
|
||||
__u32 portstatus[MAX_ROOT_PORTS];
|
||||
} roothub;
|
||||
} __attribute__ ((aligned(32)));
|
||||
|
||||
/* OHCI CONTROL AND STATUS REGISTER MASKS */
|
||||
|
||||
/*
|
||||
* HcControl (control) register masks
|
||||
*/
|
||||
#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
|
||||
#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
|
||||
#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
|
||||
#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
|
||||
#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
|
||||
#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
|
||||
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
|
||||
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
||||
#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
|
||||
|
||||
/* pre-shifted values for HCFS */
|
||||
# define OHCI_USB_RESET (0 << 6)
|
||||
# define OHCI_USB_RESUME (1 << 6)
|
||||
# define OHCI_USB_OPER (2 << 6)
|
||||
# define OHCI_USB_SUSPEND (3 << 6)
|
||||
|
||||
/*
|
||||
* HcCommandStatus (cmdstatus) register masks
|
||||
*/
|
||||
#define OHCI_HCR (1 << 0) /* host controller reset */
|
||||
#define OHCI_CLF (1 << 1) /* control list filled */
|
||||
#define OHCI_BLF (1 << 2) /* bulk list filled */
|
||||
#define OHCI_OCR (1 << 3) /* ownership change request */
|
||||
#define OHCI_SOC (3 << 16) /* scheduling overrun count */
|
||||
|
||||
/*
|
||||
* masks used with interrupt registers:
|
||||
* HcInterruptStatus (intrstatus)
|
||||
* HcInterruptEnable (intrenable)
|
||||
* HcInterruptDisable (intrdisable)
|
||||
*/
|
||||
#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
|
||||
#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
|
||||
#define OHCI_INTR_SF (1 << 2) /* start frame */
|
||||
#define OHCI_INTR_RD (1 << 3) /* resume detect */
|
||||
#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
|
||||
#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
|
||||
#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
|
||||
#define OHCI_INTR_OC (1 << 30) /* ownership change */
|
||||
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
|
||||
|
||||
/* Virtual Root HUB */
|
||||
struct virt_root_hub {
|
||||
int devnum; /* Address of Root Hub endpoint */
|
||||
void *dev; /* was urb */
|
||||
void *int_addr;
|
||||
int send;
|
||||
int interval;
|
||||
};
|
||||
|
||||
/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
|
||||
|
||||
/* destination of request */
|
||||
#define RH_INTERFACE 0x01
|
||||
#define RH_ENDPOINT 0x02
|
||||
#define RH_OTHER 0x03
|
||||
|
||||
#define RH_CLASS 0x20
|
||||
#define RH_VENDOR 0x40
|
||||
|
||||
/* Requests: bRequest << 8 | bmRequestType */
|
||||
#define RH_GET_STATUS 0x0080
|
||||
#define RH_CLEAR_FEATURE 0x0100
|
||||
#define RH_SET_FEATURE 0x0300
|
||||
#define RH_SET_ADDRESS 0x0500
|
||||
#define RH_GET_DESCRIPTOR 0x0680
|
||||
#define RH_SET_DESCRIPTOR 0x0700
|
||||
#define RH_GET_CONFIGURATION 0x0880
|
||||
#define RH_SET_CONFIGURATION 0x0900
|
||||
#define RH_GET_STATE 0x0280
|
||||
#define RH_GET_INTERFACE 0x0A80
|
||||
#define RH_SET_INTERFACE 0x0B00
|
||||
#define RH_SYNC_FRAME 0x0C80
|
||||
/* Our Vendor Specific Request */
|
||||
#define RH_SET_EP 0x2000
|
||||
|
||||
|
||||
/* Hub port features */
|
||||
#define RH_PORT_CONNECTION 0x00
|
||||
#define RH_PORT_ENABLE 0x01
|
||||
#define RH_PORT_SUSPEND 0x02
|
||||
#define RH_PORT_OVER_CURRENT 0x03
|
||||
#define RH_PORT_RESET 0x04
|
||||
#define RH_PORT_POWER 0x08
|
||||
#define RH_PORT_LOW_SPEED 0x09
|
||||
|
||||
#define RH_C_PORT_CONNECTION 0x10
|
||||
#define RH_C_PORT_ENABLE 0x11
|
||||
#define RH_C_PORT_SUSPEND 0x12
|
||||
#define RH_C_PORT_OVER_CURRENT 0x13
|
||||
#define RH_C_PORT_RESET 0x14
|
||||
|
||||
/* Hub features */
|
||||
#define RH_C_HUB_LOCAL_POWER 0x00
|
||||
#define RH_C_HUB_OVER_CURRENT 0x01
|
||||
|
||||
#define RH_DEVICE_REMOTE_WAKEUP 0x00
|
||||
#define RH_ENDPOINT_STALL 0x01
|
||||
|
||||
#define RH_ACK 0x01
|
||||
#define RH_REQ_ERR -1
|
||||
#define RH_NACK 0x00
|
||||
|
||||
|
||||
/* OHCI ROOT HUB REGISTER MASKS */
|
||||
|
||||
/* roothub.portstatus [i] bits */
|
||||
#define RH_PS_CCS 0x00000001 /* current connect status */
|
||||
#define RH_PS_PES 0x00000002 /* port enable status */
|
||||
#define RH_PS_PSS 0x00000004 /* port suspend status */
|
||||
#define RH_PS_POCI 0x00000008 /* port over current indicator */
|
||||
#define RH_PS_PRS 0x00000010 /* port reset status */
|
||||
#define RH_PS_PPS 0x00000100 /* port power status */
|
||||
#define RH_PS_LSDA 0x00000200 /* low speed device attached */
|
||||
#define RH_PS_CSC 0x00010000 /* connect status change */
|
||||
#define RH_PS_PESC 0x00020000 /* port enable status change */
|
||||
#define RH_PS_PSSC 0x00040000 /* port suspend status change */
|
||||
#define RH_PS_OCIC 0x00080000 /* over current indicator change */
|
||||
#define RH_PS_PRSC 0x00100000 /* port reset status change */
|
||||
|
||||
/* roothub.status bits */
|
||||
#define RH_HS_LPS 0x00000001 /* local power status */
|
||||
#define RH_HS_OCI 0x00000002 /* over current indicator */
|
||||
#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
|
||||
#define RH_HS_LPSC 0x00010000 /* local power status change */
|
||||
#define RH_HS_OCIC 0x00020000 /* over current indicator change */
|
||||
#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
|
||||
|
||||
/* roothub.b masks */
|
||||
#define RH_B_DR 0x0000ffff /* device removable flags */
|
||||
#define RH_B_PPCM 0xffff0000 /* port power control mask */
|
||||
|
||||
/* roothub.a masks */
|
||||
#define RH_A_NDP (0xff << 0) /* number of downstream ports */
|
||||
#define RH_A_PSM (1 << 8) /* power switching mode */
|
||||
#define RH_A_NPS (1 << 9) /* no power switching */
|
||||
#define RH_A_DT (1 << 10) /* device type (mbz) */
|
||||
#define RH_A_OCPM (1 << 11) /* over current protection mode */
|
||||
#define RH_A_NOCP (1 << 12) /* no over current protection */
|
||||
#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
|
||||
|
||||
/* urb */
|
||||
#define N_URB_TD 48
|
||||
struct urb_priv {
|
||||
struct ed *ed;
|
||||
__u16 length; /* number of tds associated with this request */
|
||||
__u16 td_cnt; /* number of tds already serviced */
|
||||
int state;
|
||||
unsigned long pipe;
|
||||
int actual_length;
|
||||
struct td *td[N_URB_TD]; /* list pointer to all corresponding TDs
|
||||
associated with this request */
|
||||
};
|
||||
#define URB_DEL 1
|
||||
|
||||
/*
|
||||
* This is the full ohci controller description
|
||||
*
|
||||
* Note how the "proper" USB information is just
|
||||
* a subset of what the full implementation needs. (Linus)
|
||||
*/
|
||||
|
||||
|
||||
struct ohci {
|
||||
struct ohci_hcca *hcca; /* hcca */
|
||||
/*dma_addr_t hcca_dma; */
|
||||
|
||||
int irq;
|
||||
int disabled; /* e.g. got a UE, we're hung */
|
||||
int sleeping;
|
||||
unsigned long flags; /* for HC bugs */
|
||||
|
||||
struct ohci_regs *regs; /* OHCI controller's memory */
|
||||
|
||||
struct ed *ed_rm_list[2]; /* lists of all endpoints to be removed */
|
||||
struct ed *ed_bulktail; /* last endpoint of bulk list */
|
||||
struct ed *ed_controltail; /* last endpoint of control list */
|
||||
int intrstatus;
|
||||
__u32 hc_control; /* copy of the hc control reg */
|
||||
struct usb_device *dev[32];
|
||||
struct virt_root_hub rh;
|
||||
|
||||
const char *slot_name;
|
||||
};
|
||||
|
||||
#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
|
||||
|
||||
struct ohci_device {
|
||||
struct ed ed[NUM_EDS];
|
||||
int ed_cnt;
|
||||
};
|
||||
|
||||
/* hcd */
|
||||
/* endpoint */
|
||||
static int ep_link(struct ohci *ohci, struct ed *ed);
|
||||
static int ep_unlink(struct ohci *ohci, struct ed *ed);
|
||||
static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* we need more TDs than EDs */
|
||||
#define NUM_TD 64
|
||||
|
||||
/* +1 so we can align the storage */
|
||||
struct td gtd[NUM_TD + 1];
|
||||
|
||||
/* pointers to aligned storage */
|
||||
struct td *ptd;
|
||||
|
||||
/* TDs ... */
|
||||
static inline struct td *td_alloc(struct usb_device *usb_dev)
|
||||
{
|
||||
int i;
|
||||
struct td *td;
|
||||
|
||||
td = NULL;
|
||||
for (i = 0; i < NUM_TD; i++) {
|
||||
if (ptd[i].usb_dev == NULL) {
|
||||
td = &ptd[i];
|
||||
td->usb_dev = usb_dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return td;
|
||||
}
|
||||
|
||||
static inline void ed_free(struct ed *ed)
|
||||
{
|
||||
ed->usb_dev = NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,522 @@
|
|||
/*
|
||||
* armboot - Startup Code for ARM920 CPU-core
|
||||
*
|
||||
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
|
||||
* Copyright (c) 2002 Gary Jennejohn <garyj@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 <asm-offsets.h>
|
||||
#include <common.h>
|
||||
#include <config.h>
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Jump vector table as in table 3.1 in [1]
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
.globl _start
|
||||
_start: b start_code
|
||||
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
|
||||
|
||||
.balignl 16,0xdeadbeef
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Startup Code (called from the ARM reset exception vector)
|
||||
*
|
||||
* do important init only if we don't start from memory!
|
||||
* relocate armboot to ram
|
||||
* setup stack
|
||||
* jump to second stage
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.globl _TEXT_BASE
|
||||
_TEXT_BASE:
|
||||
.word CONFIG_SYS_TEXT_BASE
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
* Subtracting _start from them lets the linker put their
|
||||
* relative position in the executable instead of leaving
|
||||
* them null.
|
||||
*/
|
||||
.globl _bss_start_ofs
|
||||
_bss_start_ofs:
|
||||
.word __bss_start - _start
|
||||
|
||||
.globl _bss_end_ofs
|
||||
_bss_end_ofs:
|
||||
.word __bss_end__ - _start
|
||||
|
||||
.globl _end_ofs
|
||||
_end_ofs:
|
||||
.word _end - _start
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
||||
.globl IRQ_STACK_START_IN
|
||||
IRQ_STACK_START_IN:
|
||||
.word 0x0badc0de
|
||||
|
||||
/*
|
||||
* the actual start code
|
||||
*/
|
||||
|
||||
start_code:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0, cpsr
|
||||
bic r0, r0, #0x1f
|
||||
orr r0, r0, #0xd3
|
||||
msr cpsr, r0
|
||||
|
||||
#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
|
||||
/*
|
||||
* relocate exception table
|
||||
*/
|
||||
ldr r0, =_start
|
||||
ldr r1, =0x0
|
||||
mov r2, #16
|
||||
copyex:
|
||||
subs r2, r2, #1
|
||||
ldr r3, [r0], #4
|
||||
str r3, [r1], #4
|
||||
bne copyex
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_S3C24X0
|
||||
/* turn off the watchdog */
|
||||
|
||||
# if defined(CONFIG_S3C2400)
|
||||
# define pWTCON 0x15300000
|
||||
# define INTMSK 0x14400008 /* Interrupt-Controller base addresses */
|
||||
# define CLKDIVN 0x14800014 /* clock divisor register */
|
||||
#else
|
||||
# define pWTCON 0x53000000
|
||||
# define INTMSK 0x4A000008 /* Interrupt-Controller base addresses */
|
||||
# define INTSUBMSK 0x4A00001C
|
||||
# define CLKDIVN 0x4C000014 /* clock divisor register */
|
||||
# endif
|
||||
|
||||
ldr r0, =pWTCON
|
||||
mov r1, #0x0
|
||||
str r1, [r0]
|
||||
|
||||
/*
|
||||
* mask all IRQs by setting all bits in the INTMR - default
|
||||
*/
|
||||
mov r1, #0xffffffff
|
||||
ldr r0, =INTMSK
|
||||
str r1, [r0]
|
||||
# if defined(CONFIG_S3C2410)
|
||||
ldr r1, =0x3ff
|
||||
ldr r0, =INTSUBMSK
|
||||
str r1, [r0]
|
||||
# endif
|
||||
|
||||
/* FCLK:HCLK:PCLK = 1:2:4 */
|
||||
/* default FCLK is 120 MHz ! */
|
||||
ldr r0, =CLKDIVN
|
||||
mov r1, #3
|
||||
str r1, [r0]
|
||||
#endif /* CONFIG_S3C24X0 */
|
||||
|
||||
/*
|
||||
* we do sys-critical inits only at reboot,
|
||||
* not when booting from ram!
|
||||
*/
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
bl cpu_init_crit
|
||||
#endif
|
||||
|
||||
/* Set stackpointer in internal RAM to call board_init_f */
|
||||
call_board_init_f:
|
||||
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
|
||||
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
|
||||
ldr r0,=0x00000000
|
||||
bl board_init_f
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* void relocate_code (addr_sp, gd, addr_moni)
|
||||
*
|
||||
* This "function" does not return, instead it continues in RAM
|
||||
* after relocating the monitor code.
|
||||
*
|
||||
*/
|
||||
.globl relocate_code
|
||||
relocate_code:
|
||||
mov r4, r0 /* save addr_sp */
|
||||
mov r5, r1 /* save addr of gd */
|
||||
mov r6, r2 /* save addr of destination */
|
||||
|
||||
/* Set up the stack */
|
||||
stack_setup:
|
||||
mov sp, r4
|
||||
|
||||
adr r0, _start
|
||||
cmp r0, r6
|
||||
beq clear_bss /* skip relocation */
|
||||
mov r1, r6 /* r1 <- scratch for copy_loop */
|
||||
ldr r3, _bss_start_ofs
|
||||
add r2, r0, r3 /* r2 <- source end address */
|
||||
|
||||
copy_loop:
|
||||
ldmia r0!, {r9-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r9-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
blo copy_loop
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* fix .rel.dyn relocations
|
||||
*/
|
||||
ldr r0, _TEXT_BASE /* r0 <- Text base */
|
||||
sub r9, r6, r0 /* r9 <- relocation offset */
|
||||
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
|
||||
add r10, r10, r0 /* r10 <- sym table in FLASH */
|
||||
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
|
||||
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
|
||||
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
|
||||
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
|
||||
fixloop:
|
||||
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
|
||||
add r0, r0, r9 /* r0 <- location to fix up in RAM */
|
||||
ldr r1, [r2, #4]
|
||||
and r7, r1, #0xff
|
||||
cmp r7, #23 /* relative fixup? */
|
||||
beq fixrel
|
||||
cmp r7, #2 /* absolute fixup? */
|
||||
beq fixabs
|
||||
/* ignore unknown type of fixup */
|
||||
b fixnext
|
||||
fixabs:
|
||||
/* absolute fix: set location to (offset) symbol value */
|
||||
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
|
||||
add r1, r10, r1 /* r1 <- address of symbol in table */
|
||||
ldr r1, [r1, #4] /* r1 <- symbol value */
|
||||
add r1, r1, r9 /* r1 <- relocated sym addr */
|
||||
b fixnext
|
||||
fixrel:
|
||||
/* relative fix: increase location by offset */
|
||||
ldr r1, [r0]
|
||||
add r1, r1, r9
|
||||
fixnext:
|
||||
str r1, [r0]
|
||||
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
|
||||
cmp r2, r3
|
||||
blo fixloop
|
||||
#endif
|
||||
|
||||
clear_bss:
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
ldr r0, _bss_start_ofs
|
||||
ldr r1, _bss_end_ofs
|
||||
mov r4, r6 /* reloc addr */
|
||||
add r0, r0, r4
|
||||
add r1, r1, r4
|
||||
mov r2, #0x00000000 /* clear */
|
||||
|
||||
clbss_l:cmp r0, r1 /* clear loop... */
|
||||
bhs clbss_e /* if reached end of bss, exit */
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
b clbss_l
|
||||
clbss_e:
|
||||
|
||||
bl coloured_LED_init
|
||||
bl red_led_on
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are done. Do not return, instead branch to second part of board
|
||||
* initialization, now running from RAM.
|
||||
*/
|
||||
#ifdef CONFIG_NAND_SPL
|
||||
ldr r0, _nand_boot_ofs
|
||||
mov pc, r0
|
||||
|
||||
_nand_boot_ofs:
|
||||
.word nand_boot
|
||||
#else
|
||||
ldr r0, _board_init_r_ofs
|
||||
adr r1, _start
|
||||
add lr, r0, r1
|
||||
add lr, lr, r9
|
||||
/* setup parameters for board_init_r */
|
||||
mov r0, r5 /* gd_t */
|
||||
mov r1, r6 /* dest_addr */
|
||||
/* jump to it ... */
|
||||
mov pc, lr
|
||||
|
||||
_board_init_r_ofs:
|
||||
.word board_init_r - _start
|
||||
#endif
|
||||
|
||||
_rel_dyn_start_ofs:
|
||||
.word __rel_dyn_start - _start
|
||||
_rel_dyn_end_ofs:
|
||||
.word __rel_dyn_end - _start
|
||||
_dynsym_start_ofs:
|
||||
.word __dynsym_start - _start
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* CPU_init_critical registers
|
||||
*
|
||||
* setup important registers
|
||||
* setup memory timing
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
cpu_init_crit:
|
||||
/*
|
||||
* 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
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*
|
||||
* before relocating, we have to setup RAM timing
|
||||
* because memory timing is board-dependend, you will
|
||||
* find a lowlevel_init.S in your board directory.
|
||||
*/
|
||||
mov ip, lr
|
||||
|
||||
bl lowlevel_init
|
||||
|
||||
mov lr, ip
|
||||
mov pc, lr
|
||||
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* 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 ...
|
||||
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
|
||||
*/
|
||||
|
||||
.macro bad_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
ldr r2, IRQ_STACK_START_IN
|
||||
ldmia r2, {r2 - r3} @ get pc, cpsr
|
||||
add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
|
||||
|
||||
add r5, sp, #S_SP
|
||||
mov r1, lr
|
||||
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
add r7, sp, #S_PC
|
||||
stmdb r7, {sp, lr}^ @ Calling SP, LR
|
||||
str lr, [r7, #0] @ Save calling PC
|
||||
mrs r6, spsr
|
||||
str r6, [r7, #4] @ Save CPSR
|
||||
str r0, [r7, #8] @ Save OLD_R0
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_restore_user_regs
|
||||
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
|
||||
mov r0, r0
|
||||
ldr lr, [sp, #S_PC] @ Get PC
|
||||
add sp, sp, #S_FRAME_SIZE
|
||||
/* return & move spsr_svc into cpsr */
|
||||
subs pc, lr, #4
|
||||
.endm
|
||||
|
||||
.macro get_bad_stack
|
||||
ldr r13, IRQ_STACK_START_IN @ setup our mode stack
|
||||
|
||||
str lr, [r13] @ save caller lr / spsr
|
||||
mrs lr, spsr
|
||||
str lr, [r13, #4]
|
||||
|
||||
mov r13, #MODE_SVC @ prepare SVC-Mode
|
||||
@ msr spsr_c, r13
|
||||
msr spsr, r13
|
||||
mov lr, pc
|
||||
movs pc, lr
|
||||
.endm
|
||||
|
||||
.macro get_irq_stack @ setup IRQ stack
|
||||
ldr sp, IRQ_STACK_START
|
||||
.endm
|
||||
|
||||
.macro get_fiq_stack @ setup FIQ stack
|
||||
ldr sp, FIQ_STACK_START
|
||||
.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
|
||||
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
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_irq_stack
|
||||
irq_save_user_regs
|
||||
bl do_irq
|
||||
irq_restore_user_regs
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_fiq_stack
|
||||
/* someone ought to write a more effiction fiq_save_user_regs */
|
||||
irq_save_user_regs
|
||||
bl do_fiq
|
||||
irq_restore_user_regs
|
||||
|
||||
#else
|
||||
|
||||
.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
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (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).o
|
||||
|
||||
START = start.o
|
||||
|
||||
COBJS += cpu.o
|
||||
COBJS += omap925.o
|
||||
COBJS += timer.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
|
||||
all: $(obj).depend $(START) $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# (C) Copyright 2002
|
||||
# Gary Jennejohn, DENX Software Engineering, <garyj@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-common -ffixed-r8 -msoft-float
|
||||
|
||||
PLATFORM_CPPFLAGS += -march=armv4
|
||||
# =========================================================================
|
||||
#
|
||||
# Supply options according to compiler version
|
||||
#
|
||||
# =========================================================================
|
||||
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
|
||||
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.de>
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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 <arm925t.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static void cache_flush(void);
|
||||
|
||||
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();
|
||||
/* flush I/D-cache */
|
||||
cache_flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* flush I/D-cache */
|
||||
static void cache_flush (void)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
|
||||
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* (C) Copyright 2003
|
||||
* Texas Instruments <www.ti.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 <command.h>
|
||||
#include <arm925t.h>
|
||||
|
||||
#define MIF_CONFIG_REG 0xFFFECC0C
|
||||
#define FLASH_GLOBAL_CTRL_NWP 1
|
||||
|
||||
void archflashwp (void *archdata, int wp)
|
||||
{
|
||||
ulong *fgc = (ulong *) MIF_CONFIG_REG;
|
||||
|
||||
if (wp == 1)
|
||||
*fgc &= ~FLASH_GLOBAL_CTRL_NWP;
|
||||
else
|
||||
*fgc |= FLASH_GLOBAL_CTRL_NWP;
|
||||
}
|
||||
|
|
@ -0,0 +1,521 @@
|
|||
/*
|
||||
* armboot - Startup Code for ARM925 CPU-core
|
||||
*
|
||||
* Copyright (c) 2003 Texas Instruments
|
||||
*
|
||||
* ----- Adapted for OMAP1510 from ARM920 code ------
|
||||
*
|
||||
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
|
||||
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
|
||||
* Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
|
||||
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
|
||||
* Copyright (c) 2003 Kshitij <kshitij@ti.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 <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
|
||||
#if defined(CONFIG_OMAP1510)
|
||||
#include <./configs/omap1510.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* Jump vector table as in table 3.1 in [1]
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
.globl _start
|
||||
_start: b reset
|
||||
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
|
||||
|
||||
.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
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
.globl _TEXT_BASE
|
||||
_TEXT_BASE:
|
||||
.word CONFIG_SYS_TEXT_BASE
|
||||
|
||||
/*
|
||||
* These are defined in the board-specific linker script.
|
||||
* Subtracting _start from them lets the linker put their
|
||||
* relative position in the executable instead of leaving
|
||||
* them null.
|
||||
*/
|
||||
.globl _bss_start_ofs
|
||||
_bss_start_ofs:
|
||||
.word __bss_start - _start
|
||||
|
||||
.globl _bss_end_ofs
|
||||
_bss_end_ofs:
|
||||
.word __bss_end__ - _start
|
||||
|
||||
.globl _end_ofs
|
||||
_end_ofs:
|
||||
.word _end - _start
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl IRQ_STACK_START
|
||||
IRQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) */
|
||||
.globl FIQ_STACK_START
|
||||
FIQ_STACK_START:
|
||||
.word 0x0badc0de
|
||||
#endif
|
||||
|
||||
/* IRQ stack memory (calculated at run-time) + 8 bytes */
|
||||
.globl IRQ_STACK_START_IN
|
||||
IRQ_STACK_START_IN:
|
||||
.word 0x0badc0de
|
||||
|
||||
/*
|
||||
* the actual reset code
|
||||
*/
|
||||
|
||||
reset:
|
||||
/*
|
||||
* set the cpu to SVC32 mode
|
||||
*/
|
||||
mrs r0,cpsr
|
||||
bic r0,r0,#0x1f
|
||||
orr r0,r0,#0xd3
|
||||
msr cpsr,r0
|
||||
|
||||
/*
|
||||
* Set up 925T mode
|
||||
*/
|
||||
mov r1, #0x81 /* Set ARM925T configuration. */
|
||||
mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */
|
||||
|
||||
/*
|
||||
* turn off the watchdog, unlock/diable sequence
|
||||
*/
|
||||
mov r1, #0xF5
|
||||
ldr r0, =WDTIM_MODE
|
||||
strh r1, [r0]
|
||||
mov r1, #0xA0
|
||||
strh r1, [r0]
|
||||
|
||||
/*
|
||||
* mask all IRQs by setting all bits in the INTMR - default
|
||||
*/
|
||||
mov r1, #0xffffffff
|
||||
ldr r0, =REG_IHL1_MIR
|
||||
str r1, [r0]
|
||||
ldr r0, =REG_IHL2_MIR
|
||||
str r1, [r0]
|
||||
|
||||
/*
|
||||
* wait for dpll to lock
|
||||
*/
|
||||
ldr r0, =CK_DPLL1
|
||||
mov r1, #0x10
|
||||
strh r1, [r0]
|
||||
poll1:
|
||||
ldrh r1, [r0]
|
||||
ands r1, r1, #0x01
|
||||
beq poll1
|
||||
|
||||
/*
|
||||
* we do sys-critical inits only at reboot,
|
||||
* not when booting from ram!
|
||||
*/
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
bl cpu_init_crit
|
||||
#endif
|
||||
|
||||
/* Set stackpointer in internal RAM to call board_init_f */
|
||||
call_board_init_f:
|
||||
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
|
||||
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
|
||||
ldr r0,=0x00000000
|
||||
bl board_init_f
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* void relocate_code (addr_sp, gd, addr_moni)
|
||||
*
|
||||
* This "function" does not return, instead it continues in RAM
|
||||
* after relocating the monitor code.
|
||||
*
|
||||
*/
|
||||
.globl relocate_code
|
||||
relocate_code:
|
||||
mov r4, r0 /* save addr_sp */
|
||||
mov r5, r1 /* save addr of gd */
|
||||
mov r6, r2 /* save addr of destination */
|
||||
|
||||
/* Set up the stack */
|
||||
stack_setup:
|
||||
mov sp, r4
|
||||
|
||||
adr r0, _start
|
||||
cmp r0, r6
|
||||
beq clear_bss /* skip relocation */
|
||||
mov r1, r6 /* r1 <- scratch for copy_loop */
|
||||
ldr r3, _bss_start_ofs
|
||||
add r2, r0, r3 /* r2 <- source end address */
|
||||
|
||||
copy_loop:
|
||||
ldmia r0!, {r9-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r9-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
blo copy_loop
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* fix .rel.dyn relocations
|
||||
*/
|
||||
ldr r0, _TEXT_BASE /* r0 <- Text base */
|
||||
sub r9, r6, r0 /* r9 <- relocation offset */
|
||||
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
|
||||
add r10, r10, r0 /* r10 <- sym table in FLASH */
|
||||
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
|
||||
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
|
||||
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
|
||||
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
|
||||
fixloop:
|
||||
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
|
||||
add r0, r0, r9 /* r0 <- location to fix up in RAM */
|
||||
ldr r1, [r2, #4]
|
||||
and r7, r1, #0xff
|
||||
cmp r7, #23 /* relative fixup? */
|
||||
beq fixrel
|
||||
cmp r7, #2 /* absolute fixup? */
|
||||
beq fixabs
|
||||
/* ignore unknown type of fixup */
|
||||
b fixnext
|
||||
fixabs:
|
||||
/* absolute fix: set location to (offset) symbol value */
|
||||
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
|
||||
add r1, r10, r1 /* r1 <- address of symbol in table */
|
||||
ldr r1, [r1, #4] /* r1 <- symbol value */
|
||||
add r1, r1, r9 /* r1 <- relocated sym addr */
|
||||
b fixnext
|
||||
fixrel:
|
||||
/* relative fix: increase location by offset */
|
||||
ldr r1, [r0]
|
||||
add r1, r1, r9
|
||||
fixnext:
|
||||
str r1, [r0]
|
||||
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
|
||||
cmp r2, r3
|
||||
blo fixloop
|
||||
#endif
|
||||
|
||||
clear_bss:
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
ldr r0, _bss_start_ofs
|
||||
ldr r1, _bss_end_ofs
|
||||
mov r4, r6 /* reloc addr */
|
||||
add r0, r0, r4
|
||||
add r1, r1, r4
|
||||
mov r2, #0x00000000 /* clear */
|
||||
|
||||
clbss_l:cmp r0, r1 /* clear loop... */
|
||||
bhs clbss_e /* if reached end of bss, exit */
|
||||
str r2, [r0]
|
||||
add r0, r0, #4
|
||||
b clbss_l
|
||||
clbss_e:
|
||||
|
||||
bl coloured_LED_init
|
||||
bl red_led_on
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are done. Do not return, instead branch to second part of board
|
||||
* initialization, now running from RAM.
|
||||
*/
|
||||
#ifdef CONFIG_NAND_SPL
|
||||
ldr r0, _nand_boot_ofs
|
||||
mov pc, r0
|
||||
|
||||
_nand_boot_ofs:
|
||||
.word nand_boot
|
||||
#else
|
||||
ldr r0, _board_init_r_ofs
|
||||
adr r1, _start
|
||||
add lr, r0, r1
|
||||
add lr, lr, r9
|
||||
/* setup parameters for board_init_r */
|
||||
mov r0, r5 /* gd_t */
|
||||
mov r1, r6 /* dest_addr */
|
||||
/* jump to it ... */
|
||||
mov pc, lr
|
||||
|
||||
_board_init_r_ofs:
|
||||
.word board_init_r - _start
|
||||
#endif
|
||||
|
||||
_rel_dyn_start_ofs:
|
||||
.word __rel_dyn_start - _start
|
||||
_rel_dyn_end_ofs:
|
||||
.word __rel_dyn_end - _start
|
||||
_dynsym_start_ofs:
|
||||
.word __dynsym_start - _start
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* CPU_init_critical registers
|
||||
*
|
||||
* setup important registers
|
||||
* setup memory timing
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
cpu_init_crit:
|
||||
/*
|
||||
* 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
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*
|
||||
* Go setup Memory and board specific bits prior to relocation.
|
||||
*/
|
||||
mov ip, lr /* perserve link reg across call */
|
||||
bl lowlevel_init /* go setup pll,mux,memory */
|
||||
mov lr, ip /* restore link */
|
||||
mov pc, lr /* back to my caller */
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
* 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 ...
|
||||
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
|
||||
*/
|
||||
|
||||
.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, IRQ_STACK_START_IN
|
||||
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 irq_save_user_regs
|
||||
sub sp, sp, #S_FRAME_SIZE
|
||||
stmia sp, {r0 - r12} @ Calling r0-r12
|
||||
add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
|
||||
stmdb r8, {sp, lr}^ @ Calling SP, LR
|
||||
str lr, [r8, #0] @ Save calling PC
|
||||
mrs r6, spsr
|
||||
str r6, [r8, #4] @ Save CPSR
|
||||
str r0, [r8, #8] @ Save OLD_R0
|
||||
mov r0, sp
|
||||
.endm
|
||||
|
||||
.macro irq_restore_user_regs
|
||||
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
|
||||
mov r0, r0
|
||||
ldr lr, [sp, #S_PC] @ Get PC
|
||||
add sp, sp, #S_FRAME_SIZE
|
||||
subs pc, lr, #4 @ return & move spsr_svc into cpsr
|
||||
.endm
|
||||
|
||||
.macro get_bad_stack
|
||||
ldr r13, IRQ_STACK_START_IN
|
||||
|
||||
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_irq_stack @ setup IRQ stack
|
||||
ldr sp, IRQ_STACK_START
|
||||
.endm
|
||||
|
||||
.macro get_fiq_stack @ setup FIQ stack
|
||||
ldr sp, FIQ_STACK_START
|
||||
.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
|
||||
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
|
||||
|
||||
#ifdef CONFIG_USE_IRQ
|
||||
|
||||
.align 5
|
||||
irq:
|
||||
get_irq_stack
|
||||
irq_save_user_regs
|
||||
bl do_irq
|
||||
irq_restore_user_regs
|
||||
|
||||
.align 5
|
||||
fiq:
|
||||
get_fiq_stack
|
||||
/* someone ought to write a more effiction fiq_save_user_regs */
|
||||
irq_save_user_regs
|
||||
bl do_fiq
|
||||
irq_restore_user_regs
|
||||
|
||||
#else
|
||||
|
||||
.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
|
||||
|
||||
.align 5
|
||||
.globl reset_cpu
|
||||
reset_cpu:
|
||||
ldr r1, rstctl1 /* get clkm1 reset ctl */
|
||||
mov r3, #0x3 /* dsp_en + arm_rst = global reset */
|
||||
strh r3, [r1] /* force reset */
|
||||
mov r0, r0
|
||||
_loop_forever:
|
||||
b _loop_forever
|
||||
rstctl1:
|
||||
.word 0xfffece10
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* (C) Copyright 2009
|
||||
* 2N Telekomunikace, <www.2n.cz>
|
||||
*
|
||||
* (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
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@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 <arm925t.h>
|
||||
#include <configs/omap1510.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define TIMER_LOAD_VAL 0xffffffff
|
||||
#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV))
|
||||
|
||||
static uint32_t timestamp;
|
||||
static uint32_t lastdec;
|
||||
|
||||
/* nothing really to do with interrupts, just starts up a counter. */
|
||||
int timer_init (void)
|
||||
{
|
||||
/* Start the decrementer ticking down from 0xffffffff */
|
||||
__raw_writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + LOAD_TIM);
|
||||
__raw_writel(MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE |
|
||||
(CONFIG_SYS_PTV << MPUTIM_PTV_BIT),
|
||||
CONFIG_SYS_TIMERBASE + CNTL_TIMER);
|
||||
|
||||
/* init the timestamp and lastdec value */
|
||||
lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) /
|
||||
(TIMER_CLOCK / CONFIG_SYS_HZ);
|
||||
timestamp = 0; /* start "advancing" time stamp from 0 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* timer without interrupts
|
||||
*/
|
||||
ulong get_timer (ulong base)
|
||||
{
|
||||
return get_timer_masked () - base;
|
||||
}
|
||||
|
||||
/* delay x useconds AND preserve advance timestamp value */
|
||||
void __udelay (unsigned long usec)
|
||||
{
|
||||
int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000;
|
||||
uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
|
||||
|
||||
while (tmo > 0) {
|
||||
now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM);
|
||||
if (last < now) /* count down timer underflow */
|
||||
tmo -= TIMER_LOAD_VAL - now + last;
|
||||
else
|
||||
tmo -= last - now;
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
ulong get_timer_masked (void)
|
||||
{
|
||||
uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) /
|
||||
(TIMER_CLOCK / CONFIG_SYS_HZ);
|
||||
if (lastdec < now) /* count down timer underflow */
|
||||
timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) -
|
||||
now + lastdec;
|
||||
else
|
||||
timestamp += lastdec - now;
|
||||
lastdec = now;
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return CONFIG_SYS_HZ;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#
|
||||
# (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).o
|
||||
|
||||
START = start.o
|
||||
COBJS = cpu.o cache.o
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
ifdef CONFIG_SPL_NO_CPU_SUPPORT_CODE
|
||||
START :=
|
||||
endif
|
||||
endif
|
||||
|
||||
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)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# (C) Copyright 2010
|
||||
# Marvell Semiconductor <www.marvell.com>
|
||||
# Written-by: Prafulla Wadaskar <prafulla@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(SOC).o
|
||||
|
||||
COBJS-y = cpu.o timer.o dram.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* (C) Copyright 2010
|
||||
* Marvell Semiconductor <www.marvell.com>
|
||||
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>
|
||||
* Contributor: Mahavir Jain <mjain@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/armada100.h>
|
||||
|
||||
#define UARTCLK14745KHZ (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1))
|
||||
#define SET_MRVL_ID (1<<8)
|
||||
#define L2C_RAM_SEL (1<<4)
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
u32 val;
|
||||
struct armd1cpu_registers *cpuregs =
|
||||
(struct armd1cpu_registers *) ARMD1_CPU_BASE;
|
||||
|
||||
struct armd1apb1_registers *apb1clkres =
|
||||
(struct armd1apb1_registers *) ARMD1_APBC1_BASE;
|
||||
|
||||
struct armd1mpmu_registers *mpmu =
|
||||
(struct armd1mpmu_registers *) ARMD1_MPMU_BASE;
|
||||
|
||||
/* set SEL_MRVL_ID bit in ARMADA100_CPU_CONF register */
|
||||
val = readl(&cpuregs->cpu_conf);
|
||||
val = val | SET_MRVL_ID;
|
||||
writel(val, &cpuregs->cpu_conf);
|
||||
|
||||
/* Enable Clocks for all hardware units */
|
||||
writel(0xFFFFFFFF, &mpmu->acgr);
|
||||
|
||||
/* Turn on AIB and AIB-APB Functional clock */
|
||||
writel(APBC_APBCLK | APBC_FNCLK, &apb1clkres->aib);
|
||||
|
||||
/* ensure L2 cache is not mapped as SRAM */
|
||||
val = readl(&cpuregs->cpu_conf);
|
||||
val = val & ~(L2C_RAM_SEL);
|
||||
writel(val, &cpuregs->cpu_conf);
|
||||
|
||||
/* Enable GPIO clock */
|
||||
writel(APBC_APBCLK, &apb1clkres->gpio);
|
||||
|
||||
#ifdef CONFIG_I2C_MV
|
||||
/* Enable general I2C clock */
|
||||
writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
|
||||
writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
|
||||
|
||||
/* Enable power I2C clock */
|
||||
writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
|
||||
writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enable Functional and APB clock at 14.7456MHz
|
||||
* for configured UART console
|
||||
*/
|
||||
#if (CONFIG_SYS_NS16550_COM1 == ARMD1_UART3_BASE)
|
||||
writel(UARTCLK14745KHZ, &apb1clkres->uart3);
|
||||
#elif (CONFIG_SYS_NS16550_COM1 == ARMD1_UART2_BASE)
|
||||
writel(UARTCLK14745KHZ, &apb1clkres->uart2);
|
||||
#else
|
||||
writel(UARTCLK14745KHZ, &apb1clkres->uart1);
|
||||
#endif
|
||||
icache_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
u32 id;
|
||||
struct armd1cpu_registers *cpuregs =
|
||||
(struct armd1cpu_registers *) ARMD1_CPU_BASE;
|
||||
|
||||
id = readl(&cpuregs->chip_id);
|
||||
printf("SoC: Armada 88AP%X-%X\n", (id & 0xFFF), (id >> 0x10));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C_MV
|
||||
void i2c_clk_enable(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* (C) Copyright 2010
|
||||
* Marvell Semiconductor <www.marvell.com>
|
||||
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>,
|
||||
* Contributor: Mahavir Jain <mjain@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/armada100.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* ARMADA100 DRAM controller supports upto 8 banks
|
||||
* for chip select 0 and 1
|
||||
*/
|
||||
|
||||
/*
|
||||
* DDR Memory Control Registers
|
||||
* Refer Datasheet Appendix A.17
|
||||
*/
|
||||
struct armd1ddr_map_registers {
|
||||
u32 cs; /* Memory Address Map Register -CS */
|
||||
u32 pad[3];
|
||||
};
|
||||
|
||||
struct armd1ddr_registers {
|
||||
u8 pad[0x100 - 0x000];
|
||||
struct armd1ddr_map_registers mmap[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* armd1_sdram_base - reads SDRAM Base Address Register
|
||||
*/
|
||||
u32 armd1_sdram_base(int chip_sel)
|
||||
{
|
||||
struct armd1ddr_registers *ddr_regs =
|
||||
(struct armd1ddr_registers *)ARMD1_DRAM_BASE;
|
||||
u32 result = 0;
|
||||
u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
|
||||
|
||||
if (!CS_valid)
|
||||
return 0;
|
||||
|
||||
result = readl(&ddr_regs->mmap[chip_sel].cs) & 0xFF800000;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* armd1_sdram_size - reads SDRAM size
|
||||
*/
|
||||
u32 armd1_sdram_size(int chip_sel)
|
||||
{
|
||||
struct armd1ddr_registers *ddr_regs =
|
||||
(struct armd1ddr_registers *)ARMD1_DRAM_BASE;
|
||||
u32 result = 0;
|
||||
u32 CS_valid = 0x01 & readl(&ddr_regs->mmap[chip_sel].cs);
|
||||
|
||||
if (!CS_valid)
|
||||
return 0;
|
||||
|
||||
result = readl(&ddr_regs->mmap[chip_sel].cs);
|
||||
result = (result >> 16) & 0xF;
|
||||
if (result < 0x7) {
|
||||
printf("Unknown DRAM Size\n");
|
||||
return -1;
|
||||
} else {
|
||||
return ((0x8 << (result - 0x7)) * 1024 * 1024);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_BOARD_DRAM_INIT
|
||||
int dram_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
gd->ram_size = 0;
|
||||
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
|
||||
gd->bd->bi_dram[i].start = armd1_sdram_base(i);
|
||||
gd->bd->bi_dram[i].size = armd1_sdram_size(i);
|
||||
/*
|
||||
* It is assumed that all memory banks are consecutive
|
||||
* and without gaps.
|
||||
* If the gap is found, ram_size will be reported for
|
||||
* consecutive memory only
|
||||
*/
|
||||
if (gd->bd->bi_dram[i].start != gd->ram_size)
|
||||
break;
|
||||
|
||||
gd->ram_size += gd->bd->bi_dram[i].size;
|
||||
|
||||
}
|
||||
|
||||
for (; i < CONFIG_NR_DRAM_BANKS; i++) {
|
||||
/* If above loop terminated prematurely, we need to set
|
||||
* remaining banks' start address & size as 0. Otherwise other
|
||||
* u-boot functions and Linux kernel gets wrong values which
|
||||
* could result in crash */
|
||||
gd->bd->bi_dram[i].start = 0;
|
||||
gd->bd->bi_dram[i].size = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this function is not defined here,
|
||||
* board.c alters dram bank zero configuration defined above.
|
||||
*/
|
||||
void dram_init_banksize(void)
|
||||
{
|
||||
dram_init();
|
||||
}
|
||||
#endif /* CONFIG_SYS_BOARD_DRAM_INIT */
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* (C) Copyright 2010
|
||||
* Marvell Semiconductor <www.marvell.com>
|
||||
* Written-by: Prafulla Wadaskar <prafulla@marvell.com>
|
||||
* Contributor: Mahavir Jain <mjain@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
#include <asm/arch/armada100.h>
|
||||
|
||||
/*
|
||||
* Timer registers
|
||||
* Refer Section A.6 in Datasheet
|
||||
*/
|
||||
struct armd1tmr_registers {
|
||||
u32 clk_ctrl; /* Timer clk control reg */
|
||||
u32 match[9]; /* Timer match registers */
|
||||
u32 count[3]; /* Timer count registers */
|
||||
u32 status[3];
|
||||
u32 ie[3];
|
||||
u32 preload[3]; /* Timer preload value */
|
||||
u32 preload_ctrl[3];
|
||||
u32 wdt_match_en;
|
||||
u32 wdt_match_r;
|
||||
u32 wdt_val;
|
||||
u32 wdt_sts;
|
||||
u32 icr[3];
|
||||
u32 wdt_icr;
|
||||
u32 cer; /* Timer count enable reg */
|
||||
u32 cmr;
|
||||
u32 ilr[3];
|
||||
u32 wcr;
|
||||
u32 wfar;
|
||||
u32 wsar;
|
||||
u32 cvwr;
|
||||
};
|
||||
|
||||
#define TIMER 0 /* Use TIMER 0 */
|
||||
/* Each timer has 3 match registers */
|
||||
#define MATCH_CMP(x) ((3 * TIMER) + x)
|
||||
#define TIMER_LOAD_VAL 0xffffffff
|
||||
#define COUNT_RD_REQ 0x1
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
/* Using gd->tbu from timestamp and gd->tbl for lastdec */
|
||||
|
||||
/* For preventing risk of instability in reading counter value,
|
||||
* first set read request to register cvwr and then read same
|
||||
* register after it captures counter value.
|
||||
*/
|
||||
ulong read_timer(void)
|
||||
{
|
||||
struct armd1tmr_registers *armd1timers =
|
||||
(struct armd1tmr_registers *) ARMD1_TIMER_BASE;
|
||||
volatile int loop=100;
|
||||
|
||||
writel(COUNT_RD_REQ, &armd1timers->cvwr);
|
||||
while (loop--);
|
||||
return(readl(&armd1timers->cvwr));
|
||||
}
|
||||
|
||||
ulong get_timer_masked(void)
|
||||
{
|
||||
ulong now = read_timer();
|
||||
|
||||
if (now >= gd->tbl) {
|
||||
/* normal mode */
|
||||
gd->tbu += now - gd->tbl;
|
||||
} else {
|
||||
/* we have an overflow ... */
|
||||
gd->tbu += now + TIMER_LOAD_VAL - gd->tbl;
|
||||
}
|
||||
gd->tbl = now;
|
||||
|
||||
return gd->tbu;
|
||||
}
|
||||
|
||||
ulong get_timer(ulong base)
|
||||
{
|
||||
return ((get_timer_masked() / (CONFIG_SYS_HZ_CLOCK / 1000)) -
|
||||
base);
|
||||
}
|
||||
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
ulong delayticks;
|
||||
ulong endtime;
|
||||
|
||||
delayticks = (usec * (CONFIG_SYS_HZ_CLOCK / 1000000));
|
||||
endtime = get_timer_masked() + delayticks;
|
||||
|
||||
while (get_timer_masked() < endtime);
|
||||
}
|
||||
|
||||
/*
|
||||
* init the Timer
|
||||
*/
|
||||
int timer_init(void)
|
||||
{
|
||||
struct armd1apb1_registers *apb1clkres =
|
||||
(struct armd1apb1_registers *) ARMD1_APBC1_BASE;
|
||||
struct armd1tmr_registers *armd1timers =
|
||||
(struct armd1tmr_registers *) ARMD1_TIMER_BASE;
|
||||
|
||||
/* Enable Timer clock at 3.25 MHZ */
|
||||
writel(APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3), &apb1clkres->timers);
|
||||
|
||||
/* load value into timer */
|
||||
writel(0x0, &armd1timers->clk_ctrl);
|
||||
/* Use Timer 0 Match Resiger 0 */
|
||||
writel(TIMER_LOAD_VAL, &armd1timers->match[MATCH_CMP(0)]);
|
||||
/* Preload value is 0 */
|
||||
writel(0x0, &armd1timers->preload[TIMER]);
|
||||
/* Enable match comparator 0 for Timer 0 */
|
||||
writel(0x1, &armd1timers->preload_ctrl[TIMER]);
|
||||
|
||||
/* Enable timer 0 */
|
||||
writel(0x1, &armd1timers->cer);
|
||||
/* init the gd->tbu and gd->tbl value */
|
||||
gd->tbl = read_timer();
|
||||
gd->tbu = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MPMU_APRR_WDTR (1<<4)
|
||||
#define TMR_WFAR 0xbaba /* WDT Register First key */
|
||||
#define TMP_WSAR 0xeb10 /* WDT Register Second key */
|
||||
|
||||
/*
|
||||
* This function uses internal Watchdog Timer
|
||||
* based reset mechanism.
|
||||
* Steps to write watchdog registers (protected access)
|
||||
* 1. Write key value to TMR_WFAR reg.
|
||||
* 2. Write key value to TMP_WSAR reg.
|
||||
* 3. Perform write operation.
|
||||
*/
|
||||
void reset_cpu (unsigned long ignored)
|
||||
{
|
||||
struct armd1mpmu_registers *mpmu =
|
||||
(struct armd1mpmu_registers *) ARMD1_MPMU_BASE;
|
||||
struct armd1tmr_registers *armd1timers =
|
||||
(struct armd1tmr_registers *) ARMD1_TIMER_BASE;
|
||||
u32 val;
|
||||
|
||||
/* negate hardware reset to the WDT after system reset */
|
||||
val = readl(&mpmu->aprr);
|
||||
val = val | MPMU_APRR_WDTR;
|
||||
writel(val, &mpmu->aprr);
|
||||
|
||||
/* reset/enable WDT clock */
|
||||
writel(APBC_APBCLK | APBC_FNCLK | APBC_RST, &mpmu->wdtpcr);
|
||||
readl(&mpmu->wdtpcr);
|
||||
writel(APBC_APBCLK | APBC_FNCLK, &mpmu->wdtpcr);
|
||||
readl(&mpmu->wdtpcr);
|
||||
|
||||
/* clear previous WDT status */
|
||||
writel(TMR_WFAR, &armd1timers->wfar);
|
||||
writel(TMP_WSAR, &armd1timers->wsar);
|
||||
writel(0, &armd1timers->wdt_sts);
|
||||
|
||||
/* set match counter */
|
||||
writel(TMR_WFAR, &armd1timers->wfar);
|
||||
writel(TMP_WSAR, &armd1timers->wsar);
|
||||
writel(0xf, &armd1timers->wdt_match_r);
|
||||
|
||||
/* enable WDT reset */
|
||||
writel(TMR_WFAR, &armd1timers->wfar);
|
||||
writel(TMP_WSAR, &armd1timers->wsar);
|
||||
writel(0x3, &armd1timers->wdt_match_en);
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return get_timer(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
return (ulong)CONFIG_SYS_HZ;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
#
|
||||
# (C) Copyright 2000-2008
|
||||
# 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).o
|
||||
|
||||
COBJS-$(CONFIG_AT91CAP9) += at91cap9_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9260) += at91sam9260_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9G20) += at91sam9260_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9XE) += at91sam9260_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9261) += at91sam9261_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9G10) += at91sam9261_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9263) += at91sam9263_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9RL) += at91sam9rl_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9M10G45) += at91sam9m10g45_devices.o
|
||||
COBJS-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o
|
||||
COBJS-$(CONFIG_AT91_EFLASH) += eflash.o
|
||||
COBJS-$(CONFIG_AT91_LED) += led.o
|
||||
COBJS-y += clock.o
|
||||
COBJS-y += cpu.o
|
||||
COBJS-y += reset.o
|
||||
COBJS-y += timer.o
|
||||
|
||||
ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
SOBJS-y := lowlevel_init.o
|
||||
endif
|
||||
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
all: $(obj).depend $(LIB)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
* (C) Copyright 2007-2008
|
||||
* Stelian Pop <stelian@popies.net>
|
||||
* Lead Tech Design <www.leadtechdesign.com>
|
||||
*
|
||||
* (C) Copyright 2009
|
||||
* Daniel Gorsulowski <daniel.gorsulowski@esd.eu>
|
||||
* esd electronic system design gmbh <www.esd.eu>
|
||||
*
|
||||
* 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/arch/at91_common.h>
|
||||
#include <asm/arch/at91_pmc.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/io.h>
|
||||
|
||||
void at91_serial0_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 22, 1); /* TXD0 */
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 23, 0); /* RXD0 */
|
||||
writel(1 << AT91CAP9_ID_US0, &pmc->pcer);
|
||||
}
|
||||
|
||||
void at91_serial1_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTD, 0, 1); /* TXD1 */
|
||||
at91_set_a_periph(AT91_PIO_PORTD, 1, 0); /* RXD1 */
|
||||
writel(1 << AT91CAP9_ID_US1, &pmc->pcer);
|
||||
}
|
||||
|
||||
void at91_serial2_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTD, 2, 1); /* TXD2 */
|
||||
at91_set_a_periph(AT91_PIO_PORTD, 3, 0); /* RXD2 */
|
||||
writel(1 << AT91CAP9_ID_US2, &pmc->pcer);
|
||||
}
|
||||
|
||||
void at91_serial3_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTC, 30, 0); /* DRXD */
|
||||
at91_set_a_periph(AT91_PIO_PORTC, 31, 1); /* DTXD */
|
||||
writel(1 << AT91_ID_SYS, &pmc->pcer);
|
||||
}
|
||||
|
||||
void at91_serial_hw_init(void)
|
||||
{
|
||||
#ifdef CONFIG_USART0
|
||||
at91_serial0_hw_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USART1
|
||||
at91_serial1_hw_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USART2
|
||||
at91_serial2_hw_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USART3 /* DBGU */
|
||||
at91_serial3_hw_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAS_DATAFLASH
|
||||
void at91_spi0_hw_init(unsigned long cs_mask)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
|
||||
|
||||
at91_set_b_periph(AT91_PIO_PORTA, 0, 0); /* SPI0_MISO */
|
||||
at91_set_b_periph(AT91_PIO_PORTA, 1, 0); /* SPI0_MOSI */
|
||||
at91_set_b_periph(AT91_PIO_PORTA, 2, 0); /* SPI0_SPCK */
|
||||
|
||||
/* Enable clock */
|
||||
writel(1 << AT91CAP9_ID_SPI0, &pmc->pcer);
|
||||
|
||||
if (cs_mask & (1 << 0)) {
|
||||
at91_set_b_periph(AT91_PIO_PORTA, 5, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 1)) {
|
||||
at91_set_b_periph(AT91_PIO_PORTA, 3, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 2)) {
|
||||
at91_set_b_periph(AT91_PIO_PORTD, 0, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 3)) {
|
||||
at91_set_b_periph(AT91_PIO_PORTD, 1, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 4)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTA, 5, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 5)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTA, 3, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 6)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTD, 0, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 7)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTD, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void at91_spi1_hw_init(unsigned long cs_mask)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 12, 0); /* SPI1_MISO */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 13, 0); /* SPI1_MOSI */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 14, 0); /* SPI1_SPCK */
|
||||
|
||||
/* Enable clock */
|
||||
writel(1 << AT91CAP9_ID_SPI1, &pmc->pcer);
|
||||
|
||||
if (cs_mask & (1 << 0)) {
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 15, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 1)) {
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 16, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 2)) {
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 17, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 3)) {
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 18, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 4)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTB, 15, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 5)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTB, 16, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 6)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTB, 17, 1);
|
||||
}
|
||||
if (cs_mask & (1 << 7)) {
|
||||
at91_set_pio_output(AT91_PIO_PORTB, 18, 1);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACB
|
||||
void at91_macb_hw_init(void)
|
||||
{
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 21, 0); /* ETXCK_EREFCK */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 22, 0); /* ERXDV */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 25, 0); /* ERX0 */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 26, 0); /* ERX1 */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 27, 0); /* ERXER */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 28, 0); /* ETXEN */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 23, 0); /* ETX0 */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 24, 0); /* ETX1 */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 30, 0); /* EMDIO */
|
||||
at91_set_a_periph(AT91_PIO_PORTB, 29, 0); /* EMDC */
|
||||
|
||||
#ifndef CONFIG_RMII
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 25, 0); /* ECRS */
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 26, 0); /* ECOL */
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 22, 0); /* ERX2 */
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 23, 0); /* ERX3 */
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 27, 0); /* ERXCK */
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 20, 0); /* ETX2 */
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 21, 0); /* ETX3 */
|
||||
at91_set_b_periph(AT91_PIO_PORTC, 24, 0); /* ETXER */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AT91_CAN
|
||||
void at91_can_hw_init(void)
|
||||
{
|
||||
at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
|
||||
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 12, 0); /* CAN_TX */
|
||||
at91_set_a_periph(AT91_PIO_PORTA, 13, 1); /* CAN_RX */
|
||||
|
||||
/* Enable clock */
|
||||
writel(1 << AT91CAP9_ID_CAN, &pmc->pcer);
|
||||
}
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue