From patchwork Mon Jan 7 13:08:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajeshwari Birje X-Patchwork-Id: 209913 X-Patchwork-Delegate: promsoft@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id AB8962C009B for ; Tue, 8 Jan 2013 00:03:57 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 75C9D4A028; Mon, 7 Jan 2013 14:03:54 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vV6gnMXqjoQn; Mon, 7 Jan 2013 14:03:54 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5567C4A030; Mon, 7 Jan 2013 14:03:52 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 45DC04A030 for ; Mon, 7 Jan 2013 14:03:50 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UNVYTL5b46+T for ; Mon, 7 Jan 2013 14:03:48 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by theia.denx.de (Postfix) with ESMTP id 047A24A028 for ; Mon, 7 Jan 2013 14:03:45 +0100 (CET) Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MG900FG2AXTQIO0@mailout3.samsung.com> for u-boot@lists.denx.de; Mon, 07 Jan 2013 22:03:42 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.124]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 3E.19.12699.EA7CAE05; Mon, 07 Jan 2013 22:03:42 +0900 (KST) X-AuditID: cbfee61b-b7f616d00000319b-31-50eac7ae1c66 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id CD.19.12699.DA7CAE05; Mon, 07 Jan 2013 22:03:41 +0900 (KST) Received: from rajeshwari-linux.sisodomain.com ([107.108.215.115]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MG900HHWAUUOH80@mmp2.samsung.com> for u-boot@lists.denx.de; Mon, 07 Jan 2013 22:03:41 +0900 (KST) From: Rajeshwari Shinde To: u-boot@lists.denx.de Date: Mon, 07 Jan 2013 18:38:44 +0530 Message-id: <1357564126-13275-3-git-send-email-rajeshwari.s@samsung.com> X-Mailer: git-send-email 1.7.4.4 In-reply-to: <1357564126-13275-1-git-send-email-rajeshwari.s@samsung.com> References: <1357564126-13275-1-git-send-email-rajeshwari.s@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrJLMWRmVeSWpSXmKPExsWyRsSkRnfd8VcBBjdPclq83dvJ7sDocfbO DsYAxigum5TUnMyy1CJ9uwSujD+XhAs2tDNWHN3Vz9bAuDani5GTQ0LAROLH24VsELaYxIV7 64FsLg4hgaWMEgse7GGDKVq8aR4rRGI6o8TFn1eYQRJCAquYJHYtkQex2QSMJLaenMYIYosI SEj86r8KZjMLFElM7V4M1MzBISzgI/HxvQKIySKgKrHtcQxIBa+Ah8SS28tYIFYpSByb+pUV xOYU8JTo/D8LapOHxKU/u8EmsggISHybfIgFZIyEgKzEpgPMEK2X2STmbIuBsCUlDq64wTKB UXgBI8MqRtHUguSC4qT0XCO94sTc4tK8dL3k/NxNjMDwO/3vmfQOxlUNFocYBTgYlXh4Lxq8 ChBiTSwrrsw9xCjBwawkwmvTBRTiTUmsrEotyo8vKs1JLT7E6AN0yERmKdHkfGBs5JXEGxqb mJsam1oaGZmZmuIQVhLnZTz1JEBIID2xJDU7NbUgtQhmHBMHp1QDo6/TgRvGv+b1/FQK4w36 uNVbx//6xjkiDj+Uqxz6vVfKlV67dqfgf8jEaW/5/67VvWUSIW/zdrXYHKsL366EZ7gvaRE7 wbdidlzy4qmvr9asSlk29YPT0Q6z3woCDAcPxzut2+AULSYifSVT7dXpw0JVnnseCzeuu/nL 8EA096GYivr5yvN/vlJiKc5INNRiLipOBAAmChDYbAIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupkkeLIzCtJLcpLzFFi42I5/e+xoO7a468CDGb+MLJ4u7eT3YHR4+yd HYwBjFENjDYZqYkpqUUKqXnJ+SmZeem2St7B8c7xpmYGhrqGlhbmSgp5ibmptkouPgG6bpk5 QGOVFMoSc0qBQgGJxcVK+naYJoSGuOlawDRG6PqGBMH1GBmggYQ1jBl/LgkXbGhnrDi6q5+t gXFtThcjJ4eEgInE4k3zWCFsMYkL99azdTFycQgJTGeUuPjzCjNIQkhgFZPEriXyIDabgJHE 1pPTGEFsEQEJiV/9V8FsZoEiiandi4EGcXAIC/hIfHyvAGKyCKhKbHscA1LBK+AhseT2MhaI VQoSx6Z+BVvLKeAp0fl/FtQmD4lLf3YzTmDkXcDIsIpRNLUguaA4KT3XSK84Mbe4NC9dLzk/ dxMjOLyfSe9gXNVgcYhRgINRiYf3osGrACHWxLLiytxDjBIczEoivDZdQCHelMTKqtSi/Pii 0pzU4kOMPkBHTWSWEk3OB8ZeXkm8obGJuamxqaWJhYmZJQ5hJXFexlNPAoQE0hNLUrNTUwtS i2DGMXFwSjUwGn5ccHza7E86Reytk1n8lrqZstm1X20T6CgqPX19rdRhbUHWt9YztDnm98eu WlhktSZpQnyn1so2U9YN7muPHvH0DF6a1b87sWS1bqe8ycTVfMkLQyXrcqbzb87KXbl174wa 1pPCu9ZzqQmr7lfoenjackeh26LHcy5dtdKcenKnvNjUQ/smK7EUZyQaajEXFScCAPw4j4ac AgAA X-CFilter-Loop: Reflected Cc: kmpark@infradead.org, patches@linaro.org Subject: [U-Boot] [PATCH 2/4 V2] SMDK5250: Convert lowlevel_init.S to lowlevel_init.c X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This patch converts lowlevel_init.S to lowlevel_init_c.c for SMDK5250. Lowlevel.S as of now added only for SMDK5250 and same can be extended to other SOC in future. Signed-off-by: Rajeshwari Shinde --- Changes in V2: - Renamed lowlevel_init.S to lowlevel.S and moved to arch/arm/cpu/armv7/exynos/ - Moved power mode defines to power.h - Added early serial support. - Renamed mem_reset to reset. arch/arm/cpu/armv7/exynos/Makefile | 6 ++ arch/arm/cpu/armv7/exynos/lowlevel.S | 35 ++++++++ arch/arm/include/asm/arch-exynos/power.h | 8 ++ board/samsung/smdk5250/Makefile | 2 +- board/samsung/smdk5250/dmc_common.c | 4 +- board/samsung/smdk5250/dmc_init_ddr3.c | 6 +- board/samsung/smdk5250/lowlevel_init.S | 96 -------------------- board/samsung/smdk5250/lowlevel_init.c | 81 +++++++++++++++++ board/samsung/smdk5250/setup.h | 19 ++++- board/samsung/smdk5250/spl_boot.c | 140 +++++++++++++++++++++++++++-- spl/Makefile | 4 + 11 files changed, 288 insertions(+), 113 deletions(-) create mode 100644 arch/arm/cpu/armv7/exynos/lowlevel.S delete mode 100644 board/samsung/smdk5250/lowlevel_init.S create mode 100644 board/samsung/smdk5250/lowlevel_init.c diff --git a/arch/arm/cpu/armv7/exynos/Makefile b/arch/arm/cpu/armv7/exynos/Makefile index 9119961..2aa2722 100644 --- a/arch/arm/cpu/armv7/exynos/Makefile +++ b/arch/arm/cpu/armv7/exynos/Makefile @@ -22,6 +22,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o +ifdef CONFIG_SMDK5250 +ifdef CONFIG_SPL +COBJS += lowlevel.o +endif +endif + COBJS += clock.o power.o soc.o system.o pinmux.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/arch/arm/cpu/armv7/exynos/lowlevel.S b/arch/arm/cpu/armv7/exynos/lowlevel.S new file mode 100644 index 0000000..7307959 --- /dev/null +++ b/arch/arm/cpu/armv7/exynos/lowlevel.S @@ -0,0 +1,35 @@ +/* + * Lowlevel setup for SMDK5250 board based on S5PC520 + * + * Copyright (C) 2012 Samsung Electronics + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + + .globl lowlevel_init +lowlevel_init: + /* + * Set the stack pointer, although it will be overwritten by the caller + * It seems we will not boot if this function is empty. + */ + ldr sp, =CONFIG_IRAM_STACK + mov pc, lr diff --git a/arch/arm/include/asm/arch-exynos/power.h b/arch/arm/include/asm/arch-exynos/power.h index f6d0278..d6fd29e 100644 --- a/arch/arm/include/asm/arch-exynos/power.h +++ b/arch/arm/include/asm/arch-exynos/power.h @@ -874,4 +874,12 @@ void power_ps_hold_setup(void); /* Read the resume function and call it */ void power_exit_wakeup(void); + + +/* Power Down Modes + * User defined values in inform1 register + */ +#define EXYNOS_CHECK_SLEEP 0x00000BAD +#define EXYNOS_CHECK_DIDLE 0xBAD00000 +#define EXYNOS_CHECK_LPA 0xABAD0000 #endif diff --git a/board/samsung/smdk5250/Makefile b/board/samsung/smdk5250/Makefile index 47c6a5a..7eaef09 100644 --- a/board/samsung/smdk5250/Makefile +++ b/board/samsung/smdk5250/Makefile @@ -24,7 +24,6 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).o -SOBJS := lowlevel_init.o COBJS := clock_init.o COBJS += dmc_common.o dmc_init_ddr3.o @@ -37,6 +36,7 @@ endif ifdef CONFIG_SPL_BUILD COBJS += spl_boot.o +COBJS += lowlevel_init.o endif SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/samsung/smdk5250/dmc_common.c b/board/samsung/smdk5250/dmc_common.c index 109602a..f637bf9 100644 --- a/board/samsung/smdk5250/dmc_common.c +++ b/board/samsung/smdk5250/dmc_common.c @@ -175,7 +175,7 @@ void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc) writel(DMC_MEMBASECONFIG1_VAL, &dmc->membaseconfig1); } -void mem_ctrl_init() +void mem_ctrl_init(int reset) { struct spl_machine_param *param = spl_get_machine_params(); struct mem_timings *mem; @@ -185,7 +185,7 @@ void mem_ctrl_init() /* If there are any other memory variant, add their init call below */ if (param->mem_type == DDR_MODE_DDR3) { - ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size); + ret = ddr3_mem_ctrl_init(mem, param->mem_iv_size, reset); if (ret) { /* will hang if failed to init memory control */ while (1) diff --git a/board/samsung/smdk5250/dmc_init_ddr3.c b/board/samsung/smdk5250/dmc_init_ddr3.c index e050790..a5a70df 100644 --- a/board/samsung/smdk5250/dmc_init_ddr3.c +++ b/board/samsung/smdk5250/dmc_init_ddr3.c @@ -40,7 +40,8 @@ static void reset_phy_ctrl(void) writel(DDR3PHY_CTRL_PHY_RESET, &clk->lpddr3phy_ctrl); } -int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size) +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, + int reset) { unsigned int val; struct exynos5_phy_control *phy0_ctrl, *phy1_ctrl; @@ -51,7 +52,8 @@ int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size) phy1_ctrl = (struct exynos5_phy_control *)EXYNOS5_DMC_PHY1_BASE; dmc = (struct exynos5_dmc *)EXYNOS5_DMC_CTRL_BASE; - reset_phy_ctrl(); + if (reset) + reset_phy_ctrl(); /* Set Impedance Output Driver */ val = (mem->impedance << CA_CK_DRVR_DS_OFFSET) | diff --git a/board/samsung/smdk5250/lowlevel_init.S b/board/samsung/smdk5250/lowlevel_init.S deleted file mode 100644 index bc6cb6f..0000000 --- a/board/samsung/smdk5250/lowlevel_init.S +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Lowlevel setup for SMDK5250 board based on S5PC520 - * - * Copyright (C) 2012 Samsung Electronics - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -_TEXT_BASE: - .word CONFIG_SYS_TEXT_BASE - - .globl lowlevel_init -lowlevel_init: - - /* use iRAM stack in bl2 */ - ldr sp, =CONFIG_IRAM_STACK - stmdb r13!, {ip,lr} - - /* check reset status */ - ldr r0, =(EXYNOS5_POWER_BASE + INFORM1_OFFSET) - ldr r1, [r0] - - /* AFTR wakeup reset */ - ldr r2, =S5P_CHECK_DIDLE - cmp r1, r2 - beq exit_wakeup - - /* LPA wakeup reset */ - ldr r2, =S5P_CHECK_LPA - cmp r1, r2 - beq exit_wakeup - - /* Sleep wakeup reset */ - ldr r2, =S5P_CHECK_SLEEP - cmp r1, r2 - beq wakeup_reset - - /* - * If U-boot is already running in RAM, no need to relocate U-Boot. - * Memory controller must be configured before relocating U-Boot - * in ram. - */ - ldr r0, =0x0ffffff /* r0 <- Mask Bits*/ - bic r1, pc, r0 /* pc <- current addr of code */ - /* r1 <- unmasked bits of pc */ - ldr r2, _TEXT_BASE /* r2 <- original base addr in ram */ - bic r2, r2, r0 /* r2 <- unmasked bits of r2*/ - cmp r1, r2 /* compare r1, r2 */ - beq 1f /* r0 == r1 then skip sdram init */ - - /* init system clock */ - bl system_clock_init - - /* Memory initialize */ - bl mem_ctrl_init - -1: - bl tzpc_init - ldmia r13!, {ip,pc} - -wakeup_reset: - bl system_clock_init - bl mem_ctrl_init - bl tzpc_init - -exit_wakeup: - /* Load return address and jump to kernel */ - ldr r0, =(EXYNOS5_POWER_BASE + INFORM0_OFFSET) - - /* r1 = physical address of exynos5_cpu_resume function*/ - ldr r1, [r0] - - /* Jump to kernel */ - mov pc, r1 - nop - nop diff --git a/board/samsung/smdk5250/lowlevel_init.c b/board/samsung/smdk5250/lowlevel_init.c new file mode 100644 index 0000000..22bdd2b --- /dev/null +++ b/board/samsung/smdk5250/lowlevel_init.c @@ -0,0 +1,81 @@ +/* + * Lowlevel setup for SMDK5250 board based on S5PC520 + * + * Copyright (C) 2012 Samsung Electronics + * Copyright (c) 2012 The Chromium OS Authors. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "setup.h" + +/* These are the things we can do during low-level init */ +enum { + DO_WAKEUP = 1 << 0, + DO_CLOCKS = 1 << 1, + DO_MEM_RESET = 1 << 2, + DO_UART = 1 << 3, +}; + +int do_lowlevel_init(void) +{ + uint32_t reset_status; + int actions = 0; + + arch_cpu_init(); + + reset_status = power_read_reset_status(); + + switch (reset_status) { + case EXYNOS_CHECK_SLEEP: + actions = DO_CLOCKS | DO_WAKEUP; + break; + case EXYNOS_CHECK_DIDLE: + case EXYNOS_CHECK_LPA: + actions = DO_WAKEUP; + break; + default: + /* This is a normal boot (not a wake from sleep) */ + actions = DO_CLOCKS | DO_MEM_RESET | DO_UART; + } + + if (actions & DO_CLOCKS) + system_clock_init(); + + if (actions & DO_UART) { + exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE); + serial_init(); + timer_init(); + } + + if (actions & DO_CLOCKS) { + mem_ctrl_init(actions & DO_MEM_RESET); + tzpc_init(); + } + + return actions & DO_WAKEUP; +} diff --git a/board/samsung/smdk5250/setup.h b/board/samsung/smdk5250/setup.h index a159601..f1d9f79 100644 --- a/board/samsung/smdk5250/setup.h +++ b/board/samsung/smdk5250/setup.h @@ -537,9 +537,11 @@ enum { * which the DMC uses to decide how to split a memory * chunk into smaller chunks to support concurrent * accesses; may vary across boards. + * @param reset Reset DDR PHY during initialization. * @return 0 if ok, SETUP_ERR_... if there is a problem */ -int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size); +int ddr3_mem_ctrl_init(struct mem_timings *mem, unsigned long mem_iv_size, + int reset); /* * Configure ZQ I/O interface @@ -587,8 +589,21 @@ void dmc_config_memory(struct mem_timings *mem, struct exynos5_dmc *dmc); */ void update_reset_dll(struct exynos5_dmc *, enum ddr_mode); +/* + * Memory initialization + * + * @param reset Reset PHY during initialization. + */ +void mem_ctrl_init(int reset); + void sdelay(unsigned long); -void mem_ctrl_init(void); void system_clock_init(void); void tzpc_init(void); + +/** + * Init subsystems according to the reset status + * + * @return 0 for a normal boot, non-zero for a resume + */ +int do_lowlevel_init(void); #endif diff --git a/board/samsung/smdk5250/spl_boot.c b/board/samsung/smdk5250/spl_boot.c index d8f3c1e..a1c8d3d 100644 --- a/board/samsung/smdk5250/spl_boot.c +++ b/board/samsung/smdk5250/spl_boot.c @@ -20,18 +20,16 @@ * MA 02111-1307 USA */ -#include -#include +#include +#include +#include +#include +#include +#include "setup.h" -enum boot_mode { - BOOT_MODE_MMC = 4, - BOOT_MODE_SERIAL = 20, - /* Boot based on Operating Mode pin settings */ - BOOT_MODE_OM = 32, - BOOT_MODE_USB, /* Boot using USB download */ -}; +DECLARE_GLOBAL_DATA_PTR; - typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst); +typedef u32 (*spi_copy_func_t)(u32 offset, u32 nblock, u32 dst); /* * Copy U-boot from mmc to RAM: @@ -62,15 +60,49 @@ void copy_uboot_to_ram(void) } } +void memzero(void *s, size_t n) +{ + char *ptr = s; + size_t i; + + for (i = 0; i < n; i++) + *ptr++ = '\0'; +} + +/** + * Set up the U-Boot global_data pointer + * + * This sets the address of the global data, and sets up basic values. + * + * @param gdp Value to give to gd + */ +static void setup_global_data(gd_t *gdp) +{ + gd = gdp; + memzero((void *)gd, sizeof(gd_t)); + gd->flags |= GD_FLG_RELOC; + gd->baudrate = CONFIG_BAUDRATE; + gd->have_console = 1; +} + void board_init_f(unsigned long bootflag) { + __attribute__((aligned(8))) gd_t local_gd; __attribute__((noreturn)) void (*uboot)(void); + + setup_global_data(&local_gd); + + if (do_lowlevel_init()) + power_exit_wakeup(); + copy_uboot_to_ram(); /* Jump to U-Boot image */ uboot = (void *)CONFIG_SYS_TEXT_BASE; (*uboot)(); + /* Never returns Here */ + panic("%s: u-boot jump failed", __func__); } /* Place Holders */ @@ -83,3 +115,91 @@ void board_init_r(gd_t *id, ulong dest_addr) } void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {} + +/* + * The following functions are required when linking console library to SPL. + * + * Enabling UART in SPL u-boot requires console library. But some + * functions we needed in the console library depends on a bunch + * of library in libgeneric, like lib/ctype.o, lib/div64.o, lib/string.o, + * and lib/vsprintf.o. Adding them makes the SPL u-boot too large and not + * fit into the expected size. + * + * So we mock these functions in SPL, i.e. vsprintf(), panic(), etc., + * in order to cut its dependency. + */ +static int _vscnprintf(char *buf, size_t size, const char *fmt, va_list args) +{ + char *str = buf, *s; + char *end = str + size - 1; + ulong u; + + if (size == 0) + return -1; + + /* + * We won't implement all full functions of vsprintf(). + * We only implement %s and %u, and ignore others and directly use + * the original format string as its result. + */ + + while (*fmt && (str < end)) { + if (*fmt != '%') { + *str++ = *fmt++; + continue; + } + fmt++; + switch (*fmt) { + case '%': + *str++ = *fmt++; + break; + case 's': + fmt++; + s = va_arg(args, char *); + while (*s && (str < end)) + *str++ = *s++; + break; + case 'u': + fmt++; + u = va_arg(args, ulong); + s = simple_itoa(u); + while (*s && (str < end)) + *str++ = *s++; + break; + default: + /* Print the original string for unsupported formats */ + *str++ = '%'; + if (str < end) + *str++ = *fmt++; + } + } + *str = '\0'; + return str - buf; +} + +/* Implement vsprintf in case someone doesn't have CONFIG_SYS_VSNPRINTF */ +int vsprintf(char *buf, const char *fmt, va_list args) +{ + return _vscnprintf(buf, CONFIG_SYS_PBSIZE, fmt, args); +} + +char *simple_itoa(ulong i) +{ + /* 21 digits plus null terminator, good for 64-bit or smaller ints */ + static char local[22] __attribute__((section(".data"))); + char *p = &local[21]; + + *p-- = '\0'; + do { + *p-- = '0' + i % 10; + i /= 10; + } while (i > 0); + return p + 1; +} + +void hang(void) +{ + puts("### ERROR ### Please RESET the board ###\n"); + for (;;) + ; +} diff --git a/spl/Makefile b/spl/Makefile index 6dbb105..3aab466 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -86,6 +86,10 @@ ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) LIBS-y += $(CPUDIR)/omap-common/libomap-common.o endif +ifneq ($(CONFIG_EXYNOS4)$(CONFIG_EXYNOS5),) +LIBS-y += $(CPUDIR)/s5p-common/libs5p-common.o +endif + ifeq ($(SOC),tegra20) LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o LIBS-y += arch/$(ARCH)/cpu/tegra-common/libcputegra-common.o