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 Shinde X-Patchwork-Id: 13881 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 3E3DB23E27 for ; Mon, 7 Jan 2013 13:03:46 +0000 (UTC) Received: from mail-vb0-f41.google.com (mail-vb0-f41.google.com [209.85.212.41]) by fiordland.canonical.com (Postfix) with ESMTP id ACF1AA1820E for ; Mon, 7 Jan 2013 13:03:45 +0000 (UTC) Received: by mail-vb0-f41.google.com with SMTP id l22so19055350vbn.14 for ; Mon, 07 Jan 2013 05:03:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-auditid:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:dlp-filter:x-mtr:x-brightmail-tracker :x-brightmail-tracker:x-cfilter-loop:x-gm-message-state; bh=Xxj2L7S3b7CFSdGTsCSHazPRcDdNDrkKoDWGT0SeCpg=; b=GSiEjvkMuKM46Cv69XdxU/T8udzFffi8y5BcpO9k5NgfUAP6aSVVfEKH6N9/7+iig7 ZPPxlDCxi0j3cdnjTW3mBTdkZ6JXoMZdoQeNYiD8ud2SnjJ4zl3pPTiRZTnhDz4frufk AxH4qnf4XQvIF/R7wxPV+8AYuhqoIpCR1aWbSLYPzc6WQPQUyvZEKqi6pHQzxDPYcQeg PuAzzFMwHbMRZfy04OY1myCPqkxdOmux2zTj4RG3yKuGYHifQbd95mTL3uhlJJrmlR2N ZfrAEqtucNy7QVPoSaFk8oJkOiQnP7tua11mKTMs+T5LbGDLLZTeltRCqkN+YFFynQPq JLsQ== X-Received: by 10.220.157.9 with SMTP id z9mr82944650vcw.45.1357563825107; Mon, 07 Jan 2013 05:03:45 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp59933veb; Mon, 7 Jan 2013 05:03:44 -0800 (PST) X-Received: by 10.50.36.194 with SMTP id s2mr5651841igj.56.1357563823643; Mon, 07 Jan 2013 05:03:43 -0800 (PST) Received: from mailout1.samsung.com (mailout1.samsung.com. [203.254.224.24]) by mx.google.com with ESMTP id r2si59485784paz.235.2013.01.07.05.03.42; Mon, 07 Jan 2013 05:03:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of rajeshwari.s@samsung.com designates 203.254.224.24 as permitted sender) client-ip=203.254.224.24; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of rajeshwari.s@samsung.com designates 203.254.224.24 as permitted sender) smtp.mail=rajeshwari.s@samsung.com Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MG9000REAY2MP30@mailout1.samsung.com>; Mon, 07 Jan 2013 22:03:42 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.126]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 8E.80.01231.DA7CAE05; Mon, 07 Jan 2013 22:03:42 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-85-50eac7ad2d8f Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 1E.80.01231.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>; Mon, 07 Jan 2013 22:03:41 +0900 (KST) From: Rajeshwari Shinde To: u-boot@lists.denx.de Cc: patches@linaro.org, sjg@chromium.org, mk7.kang@samsung.com, chander.kashyap@linaro.org, kmpark@infradead.org Subject: [PATCH 2/4 V2] SMDK5250: Convert lowlevel_init.S to lowlevel_init.c 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+NgFrrPLMWRmVeSWpSXmKPExsWyRsSkTnfd8VcBBmvXMFs8XH+TxWLK4S8s Dkwed67tYQtgjOKySUnNySxLLdK3S+DK+HNJuGBDO2PF0V39bA2Ma3O6GDk5JARMJDb13WOB sMUkLtxbz9bFyMUhJLCUUeLtyQ1MXYwcYEU9azMh4tMZJRZ8ecQK4Uxkktj56iwjSDebgJHE 1pPTwGwRAQmJX/1XwWxmgSKJqd2LWUEGCQv4SHx8rwBisgioSmx7HANSwSvgIbHk9jKoGxQk jk39ygpicwp4SnT+n8UMYgsB1Vz6sxtsIouAgMS3yYdYIE6Tldh0gBnkGgmB22wSV/ZeZIKY IylxcMUNlgmMwgsYGVYxiqYWJBcUJ6XnGuoVJ+YWl+al6yXn525iBIbi6X/PpHYwrmywOMQo wMGoxMN70eBVgBBrYllxZe4hRgkOZiURXpsuoBBvSmJlVWpRfnxRaU5q8SFGH6BLJjJLiSbn A+MkryTe0NjE3NTY1NLIyMzUFIewkjgv46knAUIC6YklqdmpqQWpRTDjmDg4pRoYmbNMmKUF eWemFO9Lun7x1IyFh8+cuRWweWOqCHttSYrexvBHz7tY/0xctrX2dthu+yktK62jryz8FKC0 1/jUtvrK0xcWcOodeP1WwW0jy8wQ33cHO6Vu5v2VSjkgf4Cx9OX/lmsunZosxyxEtofuMzR7 2fSaZ6tQo2vrk60Wru8v37du+KO7SYmlOCPRUIu5qDgRAAcUFaJyAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupjkeLIzCtJLcpLzFFi42I5/e+xoO7a468CDHr+Glg8XH+TxWLK4S8s Dkwed67tYQtgjGpgtMlITUxJLVJIzUvOT8nMS7dV8g6Od443NTMw1DW0tDBXUshLzE21VXLx CdB1y8wBmq2kUJaYUwoUCkgsLlbSt8M0ITTETdcCpjFC1zckCK7HyAANJKxhzPhzSbhgQztj xdFd/WwNjGtzuhg5OCQETCR61mZ2MXICmWISF+6tZ+ti5OIQEpjOKLHgyyNWCGcik8TOV2cZ QarYBIwktp6cBmaLCEhI/Oq/CmYzCxRJTO1ezAoyVFjAR+LjewUQk0VAVWLb4xiQCl4BD4kl t5exQOxSkDg29SsriM0p4CnR+X8WM4gtBFRz6c9uxgmMvAsYGVYxiqYWJBcUJ6XnGuoVJ+YW l+al6yXn525iBAf6M6kdjCsbLA4xCnAwKvHwXjR4FSDEmlhWXJl7iFGCg1lJhNemCyjEm5JY WZValB9fVJqTWnyI0QfoqInMUqLJ+cAozCuJNzQ2MTc1NrU0sTAxs8QhrCTOy3jqSYCQQHpi SWp2ampBahHMOCYOTqkGRjaWKd2ZMiterzSQWdFrGbEy43axcaHJ586TawVuL6mMf2DsX753 edwx20Kxny7ZYtyWLW5bE+L3RZ7oLlNhM/ioOTHBxJPP5qS+d8mvdAOpYs1HbNWd79WNbfYt bEwwVC2pMPpd9pZfVD3+nG1qRc32yolHM17YPN+UmTuZXeRW0rrYWXxKLMUZiYZazEXFiQCD 92qdoQIAAA== X-CFilter-Loop: Reflected X-Gm-Message-State: ALoCoQnJSA6YFcggRG93O9C0tZjL8Zs1wKc+aCeiQ3eivHkMOJU0WVUUkKpsS1cbSe1YpZ54sVIi 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