diff options
Diffstat (limited to 'arch/arm/cpu')
24 files changed, 711 insertions, 496 deletions
diff --git a/arch/arm/cpu/arm1136/mx35/asm-offsets.c b/arch/arm/cpu/arm1136/mx35/asm-offsets.c deleted file mode 100644 index ebd7575039..0000000000 --- a/arch/arm/cpu/arm1136/mx35/asm-offsets.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#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)); - DEFINE(CLKCTL_CGR3, offsetof(struct ccm_regs, cgr3)); - - /* Multi-Layer AHB Crossbar Switch */ - DEFINE(MAX_MPR0, offsetof(struct max_regs, mpr0)); - DEFINE(MAX_SGPCR0, offsetof(struct max_regs, sgpcr0)); - DEFINE(MAX_MPR1, offsetof(struct max_regs, mpr1)); - DEFINE(MAX_SGPCR1, offsetof(struct max_regs, sgpcr1)); - DEFINE(MAX_MPR2, offsetof(struct max_regs, mpr2)); - DEFINE(MAX_SGPCR2, offsetof(struct max_regs, sgpcr2)); - DEFINE(MAX_MPR3, offsetof(struct max_regs, mpr3)); - DEFINE(MAX_SGPCR3, offsetof(struct max_regs, sgpcr3)); - DEFINE(MAX_MPR4, offsetof(struct max_regs, mpr4)); - DEFINE(MAX_SGPCR4, offsetof(struct max_regs, sgpcr4)); - DEFINE(MAX_MGPCR0, offsetof(struct max_regs, mgpcr0)); - DEFINE(MAX_MGPCR1, offsetof(struct max_regs, mgpcr1)); - DEFINE(MAX_MGPCR2, offsetof(struct max_regs, mgpcr2)); - DEFINE(MAX_MGPCR3, offsetof(struct max_regs, mgpcr3)); - DEFINE(MAX_MGPCR4, offsetof(struct max_regs, mgpcr4)); - DEFINE(MAX_MGPCR5, offsetof(struct max_regs, mgpcr5)); - - /* AHB <-> IP-Bus Interface */ - DEFINE(AIPS_MPR_0_7, offsetof(struct aips_regs, mpr_0_7)); - DEFINE(AIPS_MPR_8_15, offsetof(struct aips_regs, mpr_8_15)); - DEFINE(AIPS_PACR_0_7, offsetof(struct aips_regs, pacr_0_7)); - DEFINE(AIPS_PACR_8_15, offsetof(struct aips_regs, pacr_8_15)); - DEFINE(AIPS_PACR_16_23, offsetof(struct aips_regs, pacr_16_23)); - DEFINE(AIPS_PACR_24_31, offsetof(struct aips_regs, pacr_24_31)); - DEFINE(AIPS_OPACR_0_7, offsetof(struct aips_regs, opacr_0_7)); - DEFINE(AIPS_OPACR_8_15, offsetof(struct aips_regs, opacr_8_15)); - DEFINE(AIPS_OPACR_16_23, offsetof(struct aips_regs, opacr_16_23)); - DEFINE(AIPS_OPACR_24_31, offsetof(struct aips_regs, opacr_24_31)); - DEFINE(AIPS_OPACR_32_39, offsetof(struct aips_regs, opacr_32_39)); - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/mb86r0x/asm-offsets.c b/arch/arm/cpu/arm926ejs/mb86r0x/asm-offsets.c deleted file mode 100644 index 5fe8fa204b..0000000000 --- a/arch/arm/cpu/arm926ejs/mb86r0x/asm-offsets.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/mb86r0x.h> - -#include <linux/kbuild.h> - -int main(void) -{ - /* ddr2 controller */ - DEFINE(DDR2_DRIC, offsetof(struct mb86r0x_ddr2c, dric)); - DEFINE(DDR2_DRIC1, offsetof(struct mb86r0x_ddr2c, dric1)); - DEFINE(DDR2_DRIC2, offsetof(struct mb86r0x_ddr2c, dric2)); - DEFINE(DDR2_DRCA, offsetof(struct mb86r0x_ddr2c, drca)); - DEFINE(DDR2_DRCM, offsetof(struct mb86r0x_ddr2c, drcm)); - DEFINE(DDR2_DRCST1, offsetof(struct mb86r0x_ddr2c, drcst1)); - DEFINE(DDR2_DRCST2, offsetof(struct mb86r0x_ddr2c, drcst2)); - DEFINE(DDR2_DRCR, offsetof(struct mb86r0x_ddr2c, drcr)); - DEFINE(DDR2_DRCF, offsetof(struct mb86r0x_ddr2c, drcf)); - DEFINE(DDR2_DRASR, offsetof(struct mb86r0x_ddr2c, drasr)); - DEFINE(DDR2_DRIMS, offsetof(struct mb86r0x_ddr2c, drims)); - DEFINE(DDR2_DROS, offsetof(struct mb86r0x_ddr2c, dros)); - DEFINE(DDR2_DRIBSODT1, offsetof(struct mb86r0x_ddr2c, dribsodt1)); - DEFINE(DDR2_DROABA, offsetof(struct mb86r0x_ddr2c, droaba)); - DEFINE(DDR2_DROBS, offsetof(struct mb86r0x_ddr2c, drobs)); - - /* clock reset generator */ - DEFINE(CRG_CRPR, offsetof(struct mb86r0x_crg, crpr)); - DEFINE(CRG_CRHA, offsetof(struct mb86r0x_crg, crha)); - DEFINE(CRG_CRPA, offsetof(struct mb86r0x_crg, crpa)); - DEFINE(CRG_CRPB, offsetof(struct mb86r0x_crg, crpb)); - DEFINE(CRG_CRHB, offsetof(struct mb86r0x_crg, crhb)); - DEFINE(CRG_CRAM, offsetof(struct mb86r0x_crg, cram)); - - /* chip control module */ - DEFINE(CCNT_CDCRC, offsetof(struct mb86r0x_ccnt, cdcrc)); - - /* external bus interface */ - DEFINE(MEMC_MCFMODE0, offsetof(struct mb86r0x_memc, mcfmode[0])); - DEFINE(MEMC_MCFMODE2, offsetof(struct mb86r0x_memc, mcfmode[2])); - DEFINE(MEMC_MCFMODE4, offsetof(struct mb86r0x_memc, mcfmode[4])); - DEFINE(MEMC_MCFTIM0, offsetof(struct mb86r0x_memc, mcftim[0])); - DEFINE(MEMC_MCFTIM2, offsetof(struct mb86r0x_memc, mcftim[2])); - DEFINE(MEMC_MCFTIM4, offsetof(struct mb86r0x_memc, mcftim[4])); - DEFINE(MEMC_MCFAREA0, offsetof(struct mb86r0x_memc, mcfarea[0])); - DEFINE(MEMC_MCFAREA2, offsetof(struct mb86r0x_memc, mcfarea[2])); - DEFINE(MEMC_MCFAREA4, offsetof(struct mb86r0x_memc, mcfarea[4])); - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/mx25/asm-offsets.c b/arch/arm/cpu/arm926ejs/mx25/asm-offsets.c deleted file mode 100644 index 0e2e8bf64e..0000000000 --- a/arch/arm/cpu/arm926ejs/mx25/asm-offsets.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/imx-regs.h> - -#include <linux/kbuild.h> - -int main(void) -{ - /* Clock Control Module */ - DEFINE(CCM_CCTL, offsetof(struct ccm_regs, cctl)); - DEFINE(CCM_CGCR0, offsetof(struct ccm_regs, cgr0)); - DEFINE(CCM_CGCR1, offsetof(struct ccm_regs, cgr1)); - DEFINE(CCM_CGCR2, offsetof(struct ccm_regs, cgr2)); - DEFINE(CCM_PCDR2, offsetof(struct ccm_regs, pcdr[2])); - DEFINE(CCM_MCR, offsetof(struct ccm_regs, mcr)); - - /* Enhanced SDRAM Controller */ - DEFINE(ESDRAMC_ESDCTL0, offsetof(struct esdramc_regs, ctl0)); - DEFINE(ESDRAMC_ESDCFG0, offsetof(struct esdramc_regs, cfg0)); - DEFINE(ESDRAMC_ESDMISC, offsetof(struct esdramc_regs, misc)); - - /* Multi-Layer AHB Crossbar Switch */ - DEFINE(MAX_MPR0, offsetof(struct max_regs, mpr0)); - DEFINE(MAX_SGPCR0, offsetof(struct max_regs, sgpcr0)); - DEFINE(MAX_MPR1, offsetof(struct max_regs, mpr1)); - DEFINE(MAX_SGPCR1, offsetof(struct max_regs, sgpcr1)); - DEFINE(MAX_MPR2, offsetof(struct max_regs, mpr2)); - DEFINE(MAX_SGPCR2, offsetof(struct max_regs, sgpcr2)); - DEFINE(MAX_MPR3, offsetof(struct max_regs, mpr3)); - DEFINE(MAX_SGPCR3, offsetof(struct max_regs, sgpcr3)); - DEFINE(MAX_MPR4, offsetof(struct max_regs, mpr4)); - DEFINE(MAX_SGPCR4, offsetof(struct max_regs, sgpcr4)); - DEFINE(MAX_MGPCR0, offsetof(struct max_regs, mgpcr0)); - DEFINE(MAX_MGPCR1, offsetof(struct max_regs, mgpcr1)); - DEFINE(MAX_MGPCR2, offsetof(struct max_regs, mgpcr2)); - DEFINE(MAX_MGPCR3, offsetof(struct max_regs, mgpcr3)); - DEFINE(MAX_MGPCR4, offsetof(struct max_regs, mgpcr4)); - - /* AHB <-> IP-Bus Interface */ - DEFINE(AIPS_MPR_0_7, offsetof(struct aips_regs, mpr_0_7)); - DEFINE(AIPS_MPR_8_15, offsetof(struct aips_regs, mpr_8_15)); - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/mx27/asm-offsets.c b/arch/arm/cpu/arm926ejs/mx27/asm-offsets.c deleted file mode 100644 index 629b727745..0000000000 --- a/arch/arm/cpu/arm926ejs/mx27/asm-offsets.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/imx-regs.h> - -#include <linux/kbuild.h> - -int main(void) -{ - DEFINE(AIPI1_PSR0, IMX_AIPI1_BASE + offsetof(struct aipi_regs, psr0)); - DEFINE(AIPI1_PSR1, IMX_AIPI1_BASE + offsetof(struct aipi_regs, psr1)); - DEFINE(AIPI2_PSR0, IMX_AIPI2_BASE + offsetof(struct aipi_regs, psr0)); - DEFINE(AIPI2_PSR1, IMX_AIPI2_BASE + offsetof(struct aipi_regs, psr1)); - - DEFINE(CSCR, IMX_PLL_BASE + offsetof(struct pll_regs, cscr)); - DEFINE(MPCTL0, IMX_PLL_BASE + offsetof(struct pll_regs, mpctl0)); - DEFINE(SPCTL0, IMX_PLL_BASE + offsetof(struct pll_regs, spctl0)); - DEFINE(PCDR0, IMX_PLL_BASE + offsetof(struct pll_regs, pcdr0)); - DEFINE(PCDR1, IMX_PLL_BASE + offsetof(struct pll_regs, pcdr1)); - DEFINE(PCCR0, IMX_PLL_BASE + offsetof(struct pll_regs, pccr0)); - DEFINE(PCCR1, IMX_PLL_BASE + offsetof(struct pll_regs, pccr1)); - - DEFINE(ESDCTL0_ROF, offsetof(struct esdramc_regs, esdctl0)); - DEFINE(ESDCFG0_ROF, offsetof(struct esdramc_regs, esdcfg0)); - DEFINE(ESDCTL1_ROF, offsetof(struct esdramc_regs, esdctl1)); - DEFINE(ESDCFG1_ROF, offsetof(struct esdramc_regs, esdcfg1)); - DEFINE(ESDMISC_ROF, offsetof(struct esdramc_regs, esdmisc)); - - DEFINE(GPCR, IMX_SYSTEM_CTL_BASE + - offsetof(struct system_control_regs, gpcr)); - DEFINE(FMCR, IMX_SYSTEM_CTL_BASE + - offsetof(struct system_control_regs, fmcr)); - - return 0; -} diff --git a/arch/arm/cpu/arm926ejs/mxs/Makefile b/arch/arm/cpu/arm926ejs/mxs/Makefile index 1eee66111c..6c59494558 100644 --- a/arch/arm/cpu/arm926ejs/mxs/Makefile +++ b/arch/arm/cpu/arm926ejs/mxs/Makefile @@ -17,9 +17,69 @@ endif MKIMAGE_TARGET-$(CONFIG_MX23) = mxsimage.mx23.cfg MKIMAGE_TARGET-$(CONFIG_MX28) = mxsimage.mx28.cfg -quiet_cmd_mkimage_mxs = UIMAGE $@ +# Generate HAB-capable IVT +# +# Note on computing the post-IVT size field value for the U-Boot binary. +# The value is the result of adding the following: +# -> The size of U-Boot binary aligned to 64B (u-boot.bin) +# -> The size of IVT block aligned to 64B (u-boot.ivt) +# -> The size of U-Boot signature (u-boot.sig), 3904 B +# -> The 64B hole in front of U-Boot binary for 'struct mxs_spl_data' passing +# +quiet_cmd_mkivt_mxs = MXSIVT $@ +cmd_mkivt_mxs = \ + sz=`expr \`stat -c "%s" $^\` + 64 + 3904 + 128` ; \ + echo -n "0x402000d1 $2 0 0 0 $3 $4 0 $$sz 0 0 0 0 0 0 0" | \ + tr -s " " | xargs -d " " -i printf "%08x\n" "{}" | rev | \ + sed "s/\(.\)\(.\)/\\\\\\\\x\2\1\n/g" | xargs -i printf "{}" >$@ + +# Align binary to 64B +quiet_cmd_mkalign_mxs = MXSALGN $@ +cmd_mkalign_mxs = \ + dd if=$^ of=$@ ibs=64 conv=sync 2>/dev/null && \ + mv $@ $^ + +# Assemble the CSF file +quiet_cmd_mkcsfreq_mxs = MXSCSFR $@ +cmd_mkcsfreq_mxs = \ + ivt=$(word 1,$^) ; \ + bin=$(word 2,$^) ; \ + csf=$(word 3,$^) ; \ + sed "s@VENDOR@$(VENDOR)@g;s@BOARD@$(BOARD)@g" "$$csf" | \ + sed '/^\#\#Blocks/ d' > $@ ; \ + echo " Blocks = $2 0x0 `stat -c '%s' $$bin` \"$$bin\" , \\" >> $@ ; \ + echo " $3 0x0 0x40 \"$$ivt\"" >> $@ + +# Sign files +quiet_cmd_mkcst_mxs = MXSCST $@ +cmd_mkcst_mxs = cst -o $@ < $^ \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) + +spl/u-boot-spl.ivt: spl/u-boot-spl.bin + $(call if_changed,mkalign_mxs) + $(call if_changed,mkivt_mxs,$(CONFIG_SPL_TEXT_BASE),\ + 0x00008000,0x00008040) + +u-boot.ivt: u-boot.bin + $(call if_changed,mkalign_mxs) + $(call if_changed,mkivt_mxs,$(CONFIG_SYS_TEXT_BASE),\ + 0x40001000,0x40001040) + +spl/u-boot-spl.csf: spl/u-boot-spl.ivt spl/u-boot-spl.bin board/$(VENDOR)/$(BOARD)/sign/u-boot-spl.csf + $(call if_changed,mkcsfreq_mxs,$(CONFIG_SPL_TEXT_BASE),0x8000) + +u-boot.csf: u-boot.ivt u-boot.bin board/$(VENDOR)/$(BOARD)/sign/u-boot.csf + $(call if_changed,mkcsfreq_mxs,$(CONFIG_SYS_TEXT_BASE),0x40001000) + +%.sig: %.csf + $(call if_changed,mkcst_mxs) + +quiet_cmd_mkimage_mxs = MKIMAGE $@ cmd_mkimage_mxs = $(objtree)/tools/mkimage -n $< -T mxsimage $@ \ $(if $(KBUILD_VERBOSE:1=), >/dev/null) u-boot.sb: $(src)/$(MKIMAGE_TARGET-y) u-boot.bin spl/u-boot-spl.bin FORCE $(call if_changed,mkimage_mxs) + +u-boot-signed.sb: $(src)/mxsimage-signed.cfg u-boot.ivt u-boot.sig spl/u-boot-spl.ivt spl/u-boot-spl.sig FORCE + $(call if_changed,mkimage_mxs) diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg new file mode 100644 index 0000000000..1520bba3fb --- /dev/null +++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage-signed.cfg @@ -0,0 +1,10 @@ +SECTION 0x0 BOOTABLE + TAG LAST + LOAD 0x1000 spl/u-boot-spl.bin + LOAD 0x8000 spl/u-boot-spl.ivt + LOAD 0x8040 spl/u-boot-spl.sig + CALL HAB 0x8000 0x0 + LOAD 0x40002000 u-boot.bin + LOAD 0x40001000 u-boot.ivt + LOAD 0x40001040 u-boot.sig + CALL HAB 0x40001000 0x0 diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg index 811876736c..55510e9cd8 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg +++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg @@ -1,6 +1,6 @@ SECTION 0x0 BOOTABLE TAG LAST - LOAD 0x0 spl/u-boot-spl.bin - CALL 0x14 0x0 - LOAD 0x40000100 u-boot.bin - CALL 0x40000100 0x0 + LOAD 0x1000 spl/u-boot-spl.bin + CALL 0x1000 0x0 + LOAD 0x40002000 u-boot.bin + CALL 0x40002000 0x0 diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg index ea772f0c86..bb78cb0c84 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg +++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg @@ -1,8 +1,8 @@ SECTION 0x0 BOOTABLE TAG LAST - LOAD 0x0 spl/u-boot-spl.bin - LOAD IVT 0x8000 0x14 + LOAD 0x1000 spl/u-boot-spl.bin + LOAD IVT 0x8000 0x1000 CALL HAB 0x8000 0x0 - LOAD 0x40000100 u-boot.bin - LOAD IVT 0x8000 0x40000100 + LOAD 0x40002000 u-boot.bin + LOAD IVT 0x8000 0x40002000 CALL HAB 0x8000 0x0 diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 68c30afc48..d3e136991a 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -13,9 +13,16 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/sys_proto.h> #include <asm/gpio.h> +#include <linux/compiler.h> #include "mxs_init.h" +DECLARE_GLOBAL_DATA_PTR; +static gd_t gdata __section(".data"); +#ifdef CONFIG_SPL_SERIAL_SUPPORT +static bd_t bdata __section(".data"); +#endif + /* * This delay function is intended to be used only in early stage of boot, where * clock are not set up yet. The timer used here is reset on every boot and @@ -102,6 +109,28 @@ static uint8_t mxs_get_bootmode_index(void) return i; } +static void mxs_spl_fixup_vectors(void) +{ + /* + * Copy our vector table to 0x0, since due to HAB, we cannot + * be loaded to 0x0. We want to have working vectoring though, + * thus this fixup. Our vectoring table is PIC, so copying is + * fine. + */ + extern uint32_t _start; + memcpy(0x0, &_start, 0x60); +} + +static void mxs_spl_console_init(void) +{ +#ifdef CONFIG_SPL_SERIAL_SUPPORT + gd->bd = &bdata; + gd->baudrate = CONFIG_BAUDRATE; + serial_init(); + gd->have_console = 1; +#endif +} + void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, const iomux_cfg_t *iomux_setup, const unsigned int iomux_size) @@ -109,8 +138,14 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, struct mxs_spl_data *data = (struct mxs_spl_data *) ((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf); uint8_t bootmode = mxs_get_bootmode_index(); + gd = &gdata; + + mxs_spl_fixup_vectors(); mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size); + + mxs_spl_console_init(); + mxs_power_init(); mxs_mem_init(); diff --git a/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds index d0b482d615..f4bf8ac1dd 100644 --- a/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds +++ b/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds @@ -16,7 +16,7 @@ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { - . = 0x00000000; + . = CONFIG_SPL_TEXT_BASE; . = ALIGN(4); .text : diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index 2b15a64667..fb44cc8290 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -202,6 +202,7 @@ static void watchdog_disable(void) } #endif +#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT) void s_init(void) { /* @@ -220,22 +221,19 @@ void s_init(void) #ifdef CONFIG_SPL_BUILD save_omap_boot_params(); #endif -#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT) watchdog_disable(); timer_init(); set_uart_mux_conf(); setup_clocks_for_console(); uart_soft_reset(); -#endif #ifdef CONFIG_NOR_BOOT gd->baudrate = CONFIG_BAUDRATE; serial_init(); gd->have_console = 1; -#else +#elif defined(CONFIG_SPL_BUILD) gd = &gdata; preloader_console_init(); #endif -#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT) prcm_init(); set_mux_conf_regs(); #if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) @@ -243,8 +241,8 @@ void s_init(void) rtc32k_enable(); #endif sdram_init(); -#endif } +#endif #ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index 645c497370..9edb47502c 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -39,6 +39,9 @@ static void exynos5_uart_config(int peripheral) start = 4; count = 2; break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return; } for (i = start; i < start + count; i++) { s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); @@ -74,6 +77,9 @@ static void exynos5420_uart_config(int peripheral) start = 4; count = 2; break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return; } for (i = start; i < start + count; i++) { @@ -110,6 +116,9 @@ static int exynos5_mmc_config(int peripheral, int flags) bank = &gpio1->c4; bank_ext = NULL; break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return -1; } if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { debug("SDMMC device %d does not support 8bit mode", @@ -683,6 +692,9 @@ static void exynos4_uart_config(int peripheral) start = 4; count = 2; break; + default: + debug("%s: invalid peripheral %d", __func__, peripheral); + return; } for (i = start; i < start + count; i++) { s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); @@ -741,6 +753,21 @@ int exynos_pinmux_config(int peripheral, int flags) } #ifdef CONFIG_OF_CONTROL +static int exynos4_pinmux_decode_periph_id(const void *blob, int node) +{ + int err; + u32 cell[3]; + + err = fdtdec_get_int_array(blob, node, "interrupts", cell, + ARRAY_SIZE(cell)); + if (err) { + debug(" invalid peripheral id\n"); + return PERIPH_ID_NONE; + } + + return cell[1]; +} + static int exynos5_pinmux_decode_periph_id(const void *blob, int node) { int err; @@ -758,6 +785,8 @@ int pinmux_decode_periph_id(const void *blob, int node) { if (cpu_is_exynos5()) return exynos5_pinmux_decode_periph_id(blob, node); + else if (cpu_is_exynos4()) + return exynos4_pinmux_decode_periph_id(blob, node); else return PERIPH_ID_NONE; } diff --git a/arch/arm/cpu/armv7/mx5/asm-offsets.c b/arch/arm/cpu/armv7/mx5/asm-offsets.c deleted file mode 100644 index ddb1898f36..0000000000 --- a/arch/arm/cpu/armv7/mx5/asm-offsets.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#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 clkctl, ccr)); - DEFINE(CLKCTL_CCDR, offsetof(struct clkctl, ccdr)); - DEFINE(CLKCTL_CSR, offsetof(struct clkctl, csr)); - DEFINE(CLKCTL_CCSR, offsetof(struct clkctl, ccsr)); - DEFINE(CLKCTL_CACRR, offsetof(struct clkctl, cacrr)); - DEFINE(CLKCTL_CBCDR, offsetof(struct clkctl, cbcdr)); - DEFINE(CLKCTL_CBCMR, offsetof(struct clkctl, cbcmr)); - DEFINE(CLKCTL_CSCMR1, offsetof(struct clkctl, cscmr1)); - DEFINE(CLKCTL_CSCMR2, offsetof(struct clkctl, cscmr2)); - DEFINE(CLKCTL_CSCDR1, offsetof(struct clkctl, cscdr1)); - DEFINE(CLKCTL_CS1CDR, offsetof(struct clkctl, cs1cdr)); - DEFINE(CLKCTL_CS2CDR, offsetof(struct clkctl, cs2cdr)); - DEFINE(CLKCTL_CDCDR, offsetof(struct clkctl, cdcdr)); - DEFINE(CLKCTL_CHSCCDR, offsetof(struct clkctl, chsccdr)); - DEFINE(CLKCTL_CSCDR2, offsetof(struct clkctl, cscdr2)); - DEFINE(CLKCTL_CSCDR3, offsetof(struct clkctl, cscdr3)); - DEFINE(CLKCTL_CSCDR4, offsetof(struct clkctl, cscdr4)); - DEFINE(CLKCTL_CWDR, offsetof(struct clkctl, cwdr)); - DEFINE(CLKCTL_CDHIPR, offsetof(struct clkctl, cdhipr)); - DEFINE(CLKCTL_CDCR, offsetof(struct clkctl, cdcr)); - DEFINE(CLKCTL_CTOR, offsetof(struct clkctl, ctor)); - DEFINE(CLKCTL_CLPCR, offsetof(struct clkctl, clpcr)); - DEFINE(CLKCTL_CISR, offsetof(struct clkctl, cisr)); - DEFINE(CLKCTL_CIMR, offsetof(struct clkctl, cimr)); - DEFINE(CLKCTL_CCOSR, offsetof(struct clkctl, ccosr)); - DEFINE(CLKCTL_CGPR, offsetof(struct clkctl, cgpr)); - DEFINE(CLKCTL_CCGR0, offsetof(struct clkctl, ccgr0)); - DEFINE(CLKCTL_CCGR1, offsetof(struct clkctl, ccgr1)); - DEFINE(CLKCTL_CCGR2, offsetof(struct clkctl, ccgr2)); - DEFINE(CLKCTL_CCGR3, offsetof(struct clkctl, ccgr3)); - DEFINE(CLKCTL_CCGR4, offsetof(struct clkctl, ccgr4)); - DEFINE(CLKCTL_CCGR5, offsetof(struct clkctl, ccgr5)); - DEFINE(CLKCTL_CCGR6, offsetof(struct clkctl, ccgr6)); - DEFINE(CLKCTL_CMEOR, offsetof(struct clkctl, cmeor)); -#if defined(CONFIG_MX53) - DEFINE(CLKCTL_CCGR7, offsetof(struct clkctl, ccgr7)); -#endif - - /* DPLL */ - DEFINE(PLL_DP_CTL, offsetof(struct dpll, dp_ctl)); - DEFINE(PLL_DP_CONFIG, offsetof(struct dpll, dp_config)); - DEFINE(PLL_DP_OP, offsetof(struct dpll, dp_op)); - DEFINE(PLL_DP_MFD, offsetof(struct dpll, dp_mfd)); - DEFINE(PLL_DP_MFN, offsetof(struct dpll, dp_mfn)); - DEFINE(PLL_DP_HFS_OP, offsetof(struct dpll, dp_hfs_op)); - DEFINE(PLL_DP_HFS_MFD, offsetof(struct dpll, dp_hfs_mfd)); - DEFINE(PLL_DP_HFS_MFN, offsetof(struct dpll, dp_hfs_mfn)); - - return 0; -} diff --git a/arch/arm/cpu/armv7/socfpga/Makefile b/arch/arm/cpu/armv7/socfpga/Makefile index 3e84a0c9f9..cbe1d406df 100644 --- a/arch/arm/cpu/armv7/socfpga/Makefile +++ b/arch/arm/cpu/armv7/socfpga/Makefile @@ -8,5 +8,5 @@ # obj-y := lowlevel_init.o -obj-y += misc.o timer.o reset_manager.o system_manager.o +obj-y += misc.o timer.o reset_manager.o system_manager.o clock_manager.o obj-$(CONFIG_SPL_BUILD) += spl.o freeze_controller.o diff --git a/arch/arm/cpu/armv7/socfpga/clock_manager.c b/arch/arm/cpu/armv7/socfpga/clock_manager.c new file mode 100644 index 0000000000..23d697dee2 --- /dev/null +++ b/arch/arm/cpu/armv7/socfpga/clock_manager.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2013 Altera Corporation <www.altera.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock_manager.h> + +static const struct socfpga_clock_manager *clock_manager_base = + (void *)SOCFPGA_CLKMGR_ADDRESS; + +#define CLKMGR_BYPASS_ENABLE 1 +#define CLKMGR_BYPASS_DISABLE 0 +#define CLKMGR_STAT_IDLE 0 +#define CLKMGR_STAT_BUSY 1 +#define CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1 0 +#define CLKMGR_BYPASS_PERPLLSRC_SELECT_INPUT_MUX 1 +#define CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1 0 +#define CLKMGR_BYPASS_SDRPLLSRC_SELECT_INPUT_MUX 1 + +#define CLEAR_BGP_EN_PWRDN \ + (CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(0)| \ + CLKMGR_MAINPLLGRP_VCO_EN_SET(0)| \ + CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(0)) + +#define VCO_EN_BASE \ + (CLKMGR_MAINPLLGRP_VCO_PWRDN_SET(0)| \ + CLKMGR_MAINPLLGRP_VCO_EN_SET(1)| \ + CLKMGR_MAINPLLGRP_VCO_BGPWRDN_SET(0)) + +static inline void cm_wait_for_lock(uint32_t mask) +{ + register uint32_t inter_val; + do { + inter_val = readl(&clock_manager_base->inter) & mask; + } while (inter_val != mask); +} + +/* function to poll in the fsm busy bit */ +static inline void cm_wait_for_fsm(void) +{ + while (readl(&clock_manager_base->stat) & CLKMGR_STAT_BUSY) + ; +} + +/* + * function to write the bypass register which requires a poll of the + * busy bit + */ +static inline void cm_write_bypass(uint32_t val) +{ + writel(val, &clock_manager_base->bypass); + cm_wait_for_fsm(); +} + +/* function to write the ctrl register which requires a poll of the busy bit */ +static inline void cm_write_ctrl(uint32_t val) +{ + writel(val, &clock_manager_base->ctrl); + cm_wait_for_fsm(); +} + +/* function to write a clock register that has phase information */ +static inline void cm_write_with_phase(uint32_t value, + uint32_t reg_address, uint32_t mask) +{ + /* poll until phase is zero */ + while (readl(reg_address) & mask) + ; + + writel(value, reg_address); + + while (readl(reg_address) & mask) + ; +} + +/* + * Setup clocks while making no assumptions about previous state of the clocks. + * + * Start by being paranoid and gate all sw managed clocks + * Put all plls in bypass + * Put all plls VCO registers back to reset value (bandgap power down). + * Put peripheral and main pll src to reset value to avoid glitch. + * Delay 5 us. + * Deassert bandgap power down and set numerator and denominator + * Start 7 us timer. + * set internal dividers + * Wait for 7 us timer. + * Enable plls + * Set external dividers while plls are locking + * Wait for pll lock + * Assert/deassert outreset all. + * Take all pll's out of bypass + * Clear safe mode + * set source main and peripheral clocks + * Ungate clocks + */ + +void cm_basic_init(const cm_config_t *cfg) +{ + uint32_t start, timeout; + + /* Start by being paranoid and gate all sw managed clocks */ + + /* + * We need to disable nandclk + * and then do another apb access before disabling + * gatting off the rest of the periperal clocks. + */ + writel(~CLKMGR_PERPLLGRP_EN_NANDCLK_MASK & + readl(&clock_manager_base->per_pll_en), + &clock_manager_base->per_pll_en); + + /* DO NOT GATE OFF DEBUG CLOCKS & BRIDGE CLOCKS */ + writel(CLKMGR_MAINPLLGRP_EN_DBGTIMERCLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGTRACECLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGCLK_MASK | + CLKMGR_MAINPLLGRP_EN_DBGATCLK_MASK | + CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK | + CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK, + &clock_manager_base->main_pll_en); + + writel(0, &clock_manager_base->sdr_pll_en); + + /* now we can gate off the rest of the peripheral clocks */ + writel(0, &clock_manager_base->per_pll_en); + + /* Put all plls in bypass */ + cm_write_bypass( + CLKMGR_BYPASS_PERPLLSRC_SET( + CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | + CLKMGR_BYPASS_SDRPLLSRC_SET( + CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | + CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_ENABLE) | + CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_ENABLE) | + CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_ENABLE)); + + /* + * Put all plls VCO registers back to reset value. + * Some code might have messed with them. + */ + writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE, + &clock_manager_base->main_pll_vco); + writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE, + &clock_manager_base->per_pll_vco); + writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE, + &clock_manager_base->sdr_pll_vco); + + /* + * The clocks to the flash devices and the L4_MAIN clocks can + * glitch when coming out of safe mode if their source values + * are different from their reset value. So the trick it to + * put them back to their reset state, and change input + * after exiting safe mode but before ungating the clocks. + */ + writel(CLKMGR_PERPLLGRP_SRC_RESET_VALUE, + &clock_manager_base->per_pll_src); + writel(CLKMGR_MAINPLLGRP_L4SRC_RESET_VALUE, + &clock_manager_base->main_pll_l4src); + + /* read back for the required 5 us delay. */ + readl(&clock_manager_base->main_pll_vco); + readl(&clock_manager_base->per_pll_vco); + readl(&clock_manager_base->sdr_pll_vco); + + + /* + * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN + * with numerator and denominator. + */ + writel(cfg->main_vco_base | CLEAR_BGP_EN_PWRDN | + CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->main_pll_vco); + + writel(cfg->peri_vco_base | CLEAR_BGP_EN_PWRDN | + CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->per_pll_vco); + + writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) | + CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | + cfg->sdram_vco_base | CLEAR_BGP_EN_PWRDN | + CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK, + &clock_manager_base->sdr_pll_vco); + + /* + * Time starts here + * must wait 7 us from BGPWRDN_SET(0) to VCO_ENABLE_SET(1) + */ + reset_timer(); + start = get_timer(0); + /* timeout in unit of us as CONFIG_SYS_HZ = 1000*1000 */ + timeout = 7; + + /* main mpu */ + writel(cfg->mpuclk, &clock_manager_base->main_pll_mpuclk); + + /* main main clock */ + writel(cfg->mainclk, &clock_manager_base->main_pll_mainclk); + + /* main for dbg */ + writel(cfg->dbgatclk, &clock_manager_base->main_pll_dbgatclk); + + /* main for cfgs2fuser0clk */ + writel(cfg->cfg2fuser0clk, + &clock_manager_base->main_pll_cfgs2fuser0clk); + + /* Peri emac0 50 MHz default to RMII */ + writel(cfg->emac0clk, &clock_manager_base->per_pll_emac0clk); + + /* Peri emac1 50 MHz default to RMII */ + writel(cfg->emac1clk, &clock_manager_base->per_pll_emac1clk); + + /* Peri QSPI */ + writel(cfg->mainqspiclk, &clock_manager_base->main_pll_mainqspiclk); + + writel(cfg->perqspiclk, &clock_manager_base->per_pll_perqspiclk); + + /* Peri pernandsdmmcclk */ + writel(cfg->pernandsdmmcclk, + &clock_manager_base->per_pll_pernandsdmmcclk); + + /* Peri perbaseclk */ + writel(cfg->perbaseclk, &clock_manager_base->per_pll_perbaseclk); + + /* Peri s2fuser1clk */ + writel(cfg->s2fuser1clk, &clock_manager_base->per_pll_s2fuser1clk); + + /* 7 us must have elapsed before we can enable the VCO */ + while (get_timer(start) < timeout) + ; + + /* Enable vco */ + /* main pll vco */ + writel(cfg->main_vco_base | VCO_EN_BASE, + &clock_manager_base->main_pll_vco); + + /* periferal pll */ + writel(cfg->peri_vco_base | VCO_EN_BASE, + &clock_manager_base->per_pll_vco); + + /* sdram pll vco */ + writel(CLKMGR_SDRPLLGRP_VCO_OUTRESET_SET(0) | + CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | + cfg->sdram_vco_base | VCO_EN_BASE, + &clock_manager_base->sdr_pll_vco); + + /* L3 MP and L3 SP */ + writel(cfg->maindiv, &clock_manager_base->main_pll_maindiv); + + writel(cfg->dbgdiv, &clock_manager_base->main_pll_dbgdiv); + + writel(cfg->tracediv, &clock_manager_base->main_pll_tracediv); + + /* L4 MP, L4 SP, can0, and can1 */ + writel(cfg->perdiv, &clock_manager_base->per_pll_div); + + writel(cfg->gpiodiv, &clock_manager_base->per_pll_gpiodiv); + +#define LOCKED_MASK \ + (CLKMGR_INTER_SDRPLLLOCKED_MASK | \ + CLKMGR_INTER_PERPLLLOCKED_MASK | \ + CLKMGR_INTER_MAINPLLLOCKED_MASK) + + cm_wait_for_lock(LOCKED_MASK); + + /* write the sdram clock counters before toggling outreset all */ + writel(cfg->ddrdqsclk & CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_MASK, + &clock_manager_base->sdr_pll_ddrdqsclk); + + writel(cfg->ddr2xdqsclk & CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_MASK, + &clock_manager_base->sdr_pll_ddr2xdqsclk); + + writel(cfg->ddrdqclk & CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_MASK, + &clock_manager_base->sdr_pll_ddrdqclk); + + writel(cfg->s2fuser2clk & CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_MASK, + &clock_manager_base->sdr_pll_s2fuser2clk); + + /* + * after locking, but before taking out of bypass + * assert/deassert outresetall + */ + uint32_t mainvco = readl(&clock_manager_base->main_pll_vco); + + /* assert main outresetall */ + writel(mainvco | CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->main_pll_vco); + + uint32_t periphvco = readl(&clock_manager_base->per_pll_vco); + + /* assert pheriph outresetall */ + writel(periphvco | CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->per_pll_vco); + + /* assert sdram outresetall */ + writel(cfg->sdram_vco_base | VCO_EN_BASE| + CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(1), + &clock_manager_base->sdr_pll_vco); + + /* deassert main outresetall */ + writel(mainvco & ~CLKMGR_MAINPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->main_pll_vco); + + /* deassert pheriph outresetall */ + writel(periphvco & ~CLKMGR_PERPLLGRP_VCO_OUTRESETALL_MASK, + &clock_manager_base->per_pll_vco); + + /* deassert sdram outresetall */ + writel(CLKMGR_SDRPLLGRP_VCO_OUTRESETALL_SET(0) | + cfg->sdram_vco_base | VCO_EN_BASE, + &clock_manager_base->sdr_pll_vco); + + /* + * now that we've toggled outreset all, all the clocks + * are aligned nicely; so we can change any phase. + */ + cm_write_with_phase(cfg->ddrdqsclk, + (uint32_t)&clock_manager_base->sdr_pll_ddrdqsclk, + CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_MASK); + + /* SDRAM DDR2XDQSCLK */ + cm_write_with_phase(cfg->ddr2xdqsclk, + (uint32_t)&clock_manager_base->sdr_pll_ddr2xdqsclk, + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_MASK); + + cm_write_with_phase(cfg->ddrdqclk, + (uint32_t)&clock_manager_base->sdr_pll_ddrdqclk, + CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_MASK); + + cm_write_with_phase(cfg->s2fuser2clk, + (uint32_t)&clock_manager_base->sdr_pll_s2fuser2clk, + CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_MASK); + + /* Take all three PLLs out of bypass when safe mode is cleared. */ + cm_write_bypass( + CLKMGR_BYPASS_PERPLLSRC_SET( + CLKMGR_BYPASS_PERPLLSRC_SELECT_EOSC1) | + CLKMGR_BYPASS_SDRPLLSRC_SET( + CLKMGR_BYPASS_SDRPLLSRC_SELECT_EOSC1) | + CLKMGR_BYPASS_PERPLL_SET(CLKMGR_BYPASS_DISABLE) | + CLKMGR_BYPASS_SDRPLL_SET(CLKMGR_BYPASS_DISABLE) | + CLKMGR_BYPASS_MAINPLL_SET(CLKMGR_BYPASS_DISABLE)); + + /* clear safe mode */ + cm_write_ctrl(readl(&clock_manager_base->ctrl) | + CLKMGR_CTRL_SAFEMODE_SET(CLKMGR_CTRL_SAFEMODE_MASK)); + + /* + * now that safe mode is clear with clocks gated + * it safe to change the source mux for the flashes the the L4_MAIN + */ + writel(cfg->persrc, &clock_manager_base->per_pll_src); + writel(cfg->l4src, &clock_manager_base->main_pll_l4src); + + /* Now ungate non-hw-managed clocks */ + writel(~0, &clock_manager_base->main_pll_en); + writel(~0, &clock_manager_base->per_pll_en); + writel(~0, &clock_manager_base->sdr_pll_en); +} diff --git a/arch/arm/cpu/armv7/socfpga/spl.c b/arch/arm/cpu/armv7/socfpga/spl.c index 36a00c39b7..2ae88bbd04 100644 --- a/arch/arm/cpu/armv7/socfpga/spl.c +++ b/arch/arm/cpu/armv7/socfpga/spl.c @@ -28,10 +28,99 @@ u32 spl_boot_device(void) void spl_board_init(void) { #ifndef CONFIG_SOCFPGA_VIRTUAL_TARGET + cm_config_t cm_default_cfg = { + /* main group */ + MAIN_VCO_BASE, + CLKMGR_MAINPLLGRP_MPUCLK_CNT_SET( + CONFIG_HPS_MAINPLLGRP_MPUCLK_CNT), + CLKMGR_MAINPLLGRP_MAINCLK_CNT_SET( + CONFIG_HPS_MAINPLLGRP_MAINCLK_CNT), + CLKMGR_MAINPLLGRP_DBGATCLK_CNT_SET( + CONFIG_HPS_MAINPLLGRP_DBGATCLK_CNT), + CLKMGR_MAINPLLGRP_MAINQSPICLK_CNT_SET( + CONFIG_HPS_MAINPLLGRP_MAINQSPICLK_CNT), + CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_SET( + CONFIG_HPS_MAINPLLGRP_MAINNANDSDMMCCLK_CNT), + CLKMGR_MAINPLLGRP_CFGS2FUSER0CLK_CNT_SET( + CONFIG_HPS_MAINPLLGRP_CFGS2FUSER0CLK_CNT), + CLKMGR_MAINPLLGRP_MAINDIV_L3MPCLK_SET( + CONFIG_HPS_MAINPLLGRP_MAINDIV_L3MPCLK) | + CLKMGR_MAINPLLGRP_MAINDIV_L3SPCLK_SET( + CONFIG_HPS_MAINPLLGRP_MAINDIV_L3SPCLK) | + CLKMGR_MAINPLLGRP_MAINDIV_L4MPCLK_SET( + CONFIG_HPS_MAINPLLGRP_MAINDIV_L4MPCLK) | + CLKMGR_MAINPLLGRP_MAINDIV_L4SPCLK_SET( + CONFIG_HPS_MAINPLLGRP_MAINDIV_L4SPCLK), + CLKMGR_MAINPLLGRP_DBGDIV_DBGATCLK_SET( + CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGATCLK) | + CLKMGR_MAINPLLGRP_DBGDIV_DBGCLK_SET( + CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGCLK), + CLKMGR_MAINPLLGRP_TRACEDIV_TRACECLK_SET( + CONFIG_HPS_MAINPLLGRP_TRACEDIV_TRACECLK), + CLKMGR_MAINPLLGRP_L4SRC_L4MP_SET( + CONFIG_HPS_MAINPLLGRP_L4SRC_L4MP) | + CLKMGR_MAINPLLGRP_L4SRC_L4SP_SET( + CONFIG_HPS_MAINPLLGRP_L4SRC_L4SP), + + /* peripheral group */ + PERI_VCO_BASE, + CLKMGR_PERPLLGRP_EMAC0CLK_CNT_SET( + CONFIG_HPS_PERPLLGRP_EMAC0CLK_CNT), + CLKMGR_PERPLLGRP_EMAC1CLK_CNT_SET( + CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT), + CLKMGR_PERPLLGRP_PERQSPICLK_CNT_SET( + CONFIG_HPS_PERPLLGRP_PERQSPICLK_CNT), + CLKMGR_PERPLLGRP_PERNANDSDMMCCLK_CNT_SET( + CONFIG_HPS_PERPLLGRP_PERNANDSDMMCCLK_CNT), + CLKMGR_PERPLLGRP_PERBASECLK_CNT_SET( + CONFIG_HPS_PERPLLGRP_PERBASECLK_CNT), + CLKMGR_PERPLLGRP_S2FUSER1CLK_CNT_SET( + CONFIG_HPS_PERPLLGRP_S2FUSER1CLK_CNT), + CLKMGR_PERPLLGRP_DIV_USBCLK_SET( + CONFIG_HPS_PERPLLGRP_DIV_USBCLK) | + CLKMGR_PERPLLGRP_DIV_SPIMCLK_SET( + CONFIG_HPS_PERPLLGRP_DIV_SPIMCLK) | + CLKMGR_PERPLLGRP_DIV_CAN0CLK_SET( + CONFIG_HPS_PERPLLGRP_DIV_CAN0CLK) | + CLKMGR_PERPLLGRP_DIV_CAN1CLK_SET( + CONFIG_HPS_PERPLLGRP_DIV_CAN1CLK), + CLKMGR_PERPLLGRP_GPIODIV_GPIODBCLK_SET( + CONFIG_HPS_PERPLLGRP_GPIODIV_GPIODBCLK), + CLKMGR_PERPLLGRP_SRC_QSPI_SET( + CONFIG_HPS_PERPLLGRP_SRC_QSPI) | + CLKMGR_PERPLLGRP_SRC_NAND_SET( + CONFIG_HPS_PERPLLGRP_SRC_NAND) | + CLKMGR_PERPLLGRP_SRC_SDMMC_SET( + CONFIG_HPS_PERPLLGRP_SRC_SDMMC), + + /* sdram pll group */ + SDR_VCO_BASE, + CLKMGR_SDRPLLGRP_DDRDQSCLK_PHASE_SET( + CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE) | + CLKMGR_SDRPLLGRP_DDRDQSCLK_CNT_SET( + CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_CNT), + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_PHASE_SET( + CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE) | + CLKMGR_SDRPLLGRP_DDR2XDQSCLK_CNT_SET( + CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT), + CLKMGR_SDRPLLGRP_DDRDQCLK_PHASE_SET( + CONFIG_HPS_SDRPLLGRP_DDRDQCLK_PHASE) | + CLKMGR_SDRPLLGRP_DDRDQCLK_CNT_SET( + CONFIG_HPS_SDRPLLGRP_DDRDQCLK_CNT), + CLKMGR_SDRPLLGRP_S2FUSER2CLK_PHASE_SET( + CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE) | + CLKMGR_SDRPLLGRP_S2FUSER2CLK_CNT_SET( + CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT), + }; + debug("Freezing all I/O banks\n"); /* freeze all IO banks */ sys_mgr_frzctrl_freeze_req(); + debug("Reconfigure Clock Manager\n"); + /* reconfigure the PLLs */ + cm_basic_init(&cm_default_cfg); + /* configure the pin muxing through system manager */ sysmgr_pinmux_init(); #endif /* CONFIG_SOCFPGA_VIRTUAL_TARGET */ diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index ac1e55a708..27be451a89 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -205,7 +205,7 @@ ENTRY(cpu_init_cp15) mcr p15, 0, r0, c1, c0, 0 @ write system control register #endif -#ifdef CONFIG_ARM_ERRATA_742230 +#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072)) mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register orr r0, r0, #1 << 4 @ set bit #4 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register @@ -222,6 +222,11 @@ ENTRY(cpu_init_cp15) orr r0, r0, #1 << 11 @ set bit #11 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register #endif +#ifdef CONFIG_ARM_ERRATA_761320 + mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register + orr r0, r0, #1 << 21 @ set bit #21 + mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register +#endif mov pc, lr @ back to my caller ENDPROC(cpu_init_cp15) diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index b6eb6de5e3..7d93f59428 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -13,5 +13,4 @@ obj-y += cache_v8.o obj-y += exceptions.o obj-y += cache.o obj-y += tlb.o -obj-y += gic.o obj-y += transition.o diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S index 546a83e8f8..4b3ee6ed6f 100644 --- a/arch/arm/cpu/armv8/cache.S +++ b/arch/arm/cpu/armv8/cache.S @@ -19,23 +19,22 @@ * clean and invalidate one level cache. * * x0: cache level - * x1~x9: clobbered + * x1: 0 flush & invalidate, 1 invalidate only + * x2~x9: clobbered */ ENTRY(__asm_flush_dcache_level) - lsl x1, x0, #1 - msr csselr_el1, x1 /* select cache level */ + lsl x12, x0, #1 + msr csselr_el1, x12 /* select cache level */ isb /* sync change of cssidr_el1 */ mrs x6, ccsidr_el1 /* read the new cssidr_el1 */ and x2, x6, #7 /* x2 <- log2(cache line size)-4 */ add x2, x2, #4 /* x2 <- log2(cache line size) */ mov x3, #0x3ff and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */ - add w4, w3, w3 - sub w4, w4, 1 /* round up log2(#ways + 1) */ - clz w5, w4 /* bit position of #ways */ + clz w5, w3 /* bit position of #ways */ mov x4, #0x7fff and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */ - /* x1 <- cache level << 1 */ + /* x12 <- cache level << 1 */ /* x2 <- line length offset */ /* x3 <- number of cache ways - 1 */ /* x4 <- number of cache sets - 1 */ @@ -45,11 +44,14 @@ loop_set: mov x6, x3 /* x6 <- working copy of #ways */ loop_way: lsl x7, x6, x5 - orr x9, x1, x7 /* map way and level to cisw value */ + orr x9, x12, x7 /* map way and level to cisw value */ lsl x7, x4, x2 orr x9, x9, x7 /* map set number to cisw value */ - dc cisw, x9 /* clean & invalidate by set/way */ - subs x6, x6, #1 /* decrement the way */ + tbz w1, #0, 1f + dc isw, x9 + b 2f +1: dc cisw, x9 /* clean & invalidate by set/way */ +2: subs x6, x6, #1 /* decrement the way */ b.ge loop_way subs x4, x4, #1 /* decrement the set */ b.ge loop_set @@ -58,11 +60,14 @@ loop_way: ENDPROC(__asm_flush_dcache_level) /* - * void __asm_flush_dcache_all(void) + * void __asm_flush_dcache_all(int invalidate_only) + * + * x0: 0 flush & invalidate, 1 invalidate only * * clean and invalidate all data cache by SET/WAY. */ -ENTRY(__asm_flush_dcache_all) +ENTRY(__asm_dcache_all) + mov x1, x0 dsb sy mrs x10, clidr_el1 /* read clidr_el1 */ lsr x11, x10, #24 @@ -76,13 +81,13 @@ ENTRY(__asm_flush_dcache_all) /* x15 <- return address */ loop_level: - lsl x1, x0, #1 - add x1, x1, x0 /* x0 <- tripled cache level */ - lsr x1, x10, x1 - and x1, x1, #7 /* x1 <- cache type */ - cmp x1, #2 + lsl x12, x0, #1 + add x12, x12, x0 /* x0 <- tripled cache level */ + lsr x12, x10, x12 + and x12, x12, #7 /* x12 <- cache type */ + cmp x12, #2 b.lt skip /* skip if no cache or icache */ - bl __asm_flush_dcache_level + bl __asm_flush_dcache_level /* x1 = 0 flush, 1 invalidate */ skip: add x0, x0, #1 /* increment cache level */ cmp x11, x0 @@ -96,8 +101,24 @@ skip: finished: ret +ENDPROC(__asm_dcache_all) + +ENTRY(__asm_flush_dcache_all) + mov x16, lr + mov x0, #0 + bl __asm_dcache_all + mov lr, x16 + ret ENDPROC(__asm_flush_dcache_all) +ENTRY(__asm_invalidate_dcache_all) + mov x16, lr + mov x0, #0xffff + bl __asm_dcache_all + mov lr, x16 + ret +ENDPROC(__asm_invalidate_dcache_all) + /* * void __asm_flush_dcache_range(start, end) * diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 131fdaba3f..a96ecda7e3 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -45,15 +45,31 @@ static void mmu_setup(void) /* load TTBR0 */ el = current_el(); - if (el == 1) + if (el == 1) { asm volatile("msr ttbr0_el1, %0" : : "r" (gd->arch.tlb_addr) : "memory"); - else if (el == 2) + asm volatile("msr tcr_el1, %0" + : : "r" (TCR_FLAGS | TCR_EL1_IPS_BITS) + : "memory"); + asm volatile("msr mair_el1, %0" + : : "r" (MEMORY_ATTRIBUTES) : "memory"); + } else if (el == 2) { asm volatile("msr ttbr0_el2, %0" : : "r" (gd->arch.tlb_addr) : "memory"); - else + asm volatile("msr tcr_el2, %0" + : : "r" (TCR_FLAGS | TCR_EL2_IPS_BITS) + : "memory"); + asm volatile("msr mair_el2, %0" + : : "r" (MEMORY_ATTRIBUTES) : "memory"); + } else { asm volatile("msr ttbr0_el3, %0" : : "r" (gd->arch.tlb_addr) : "memory"); + asm volatile("msr tcr_el3, %0" + : : "r" (TCR_FLAGS | TCR_EL2_IPS_BITS) + : "memory"); + asm volatile("msr mair_el3, %0" + : : "r" (MEMORY_ATTRIBUTES) : "memory"); + } /* enable the mmu */ set_sctlr(get_sctlr() | CR_M); @@ -64,7 +80,7 @@ static void mmu_setup(void) */ void invalidate_dcache_all(void) { - __asm_flush_dcache_all(); + __asm_invalidate_dcache_all(); } /* @@ -161,6 +177,7 @@ int dcache_status(void) void icache_enable(void) { + __asm_invalidate_icache_all(); set_sctlr(get_sctlr() | CR_I); } diff --git a/arch/arm/cpu/armv8/gic.S b/arch/arm/cpu/armv8/gic.S deleted file mode 100644 index 599aa8f2ba..0000000000 --- a/arch/arm/cpu/armv8/gic.S +++ /dev/null @@ -1,106 +0,0 @@ -/* - * GIC Initialization Routines. - * - * (C) Copyright 2013 - * David Feng <fenghua@phytium.com.cn> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm-offsets.h> -#include <config.h> -#include <linux/linkage.h> -#include <asm/macro.h> -#include <asm/gic.h> - - -/************************************************************************* - * - * void gic_init(void) __attribute__((weak)); - * - * Currently, this routine only initialize secure copy of GIC - * with Security Extensions at EL3. - * - *************************************************************************/ -WEAK(gic_init) - branch_if_slave x0, 2f - - /* Initialize Distributor and SPIs */ - ldr x1, =GICD_BASE - mov w0, #0x3 /* EnableGrp0 | EnableGrp1 */ - str w0, [x1, GICD_CTLR] /* Secure GICD_CTLR */ - ldr w0, [x1, GICD_TYPER] - and w2, w0, #0x1f /* ITLinesNumber */ - cbz w2, 2f /* No SPIs */ - add x1, x1, (GICD_IGROUPRn + 4) - mov w0, #~0 /* Config SPIs as Grp1 */ -1: str w0, [x1], #0x4 - sub w2, w2, #0x1 - cbnz w2, 1b - - /* Initialize SGIs and PPIs */ -2: ldr x1, =GICD_BASE - mov w0, #~0 /* Config SGIs and PPIs as Grp1 */ - str w0, [x1, GICD_IGROUPRn] /* GICD_IGROUPR0 */ - mov w0, #0x1 /* Enable SGI 0 */ - str w0, [x1, GICD_ISENABLERn] - - /* Initialize Cpu Interface */ - ldr x1, =GICC_BASE - mov w0, #0x1e7 /* Disable IRQ/FIQ Bypass & */ - /* Enable Ack Group1 Interrupt & */ - /* EnableGrp0 & EnableGrp1 */ - str w0, [x1, GICC_CTLR] /* Secure GICC_CTLR */ - - mov w0, #0x1 << 7 /* Non-Secure access to GICC_PMR */ - str w0, [x1, GICC_PMR] - - ret -ENDPROC(gic_init) - - -/************************************************************************* - * - * void gic_send_sgi(u64 sgi) __attribute__((weak)); - * - *************************************************************************/ -WEAK(gic_send_sgi) - ldr x1, =GICD_BASE - mov w2, #0x8000 - movk w2, #0x100, lsl #16 - orr w2, w2, w0 - str w2, [x1, GICD_SGIR] - ret -ENDPROC(gic_send_sgi) - - -/************************************************************************* - * - * void wait_for_wakeup(void) __attribute__((weak)); - * - * Wait for SGI 0 from master. - * - *************************************************************************/ -WEAK(wait_for_wakeup) - ldr x1, =GICC_BASE -0: wfi - ldr w0, [x1, GICC_AIAR] - str w0, [x1, GICC_AEOIR] - cbnz w0, 0b - ret -ENDPROC(wait_for_wakeup) - - -/************************************************************************* - * - * void smp_kick_all_cpus(void) __attribute__((weak)); - * - *************************************************************************/ -WEAK(smp_kick_all_cpus) - /* Kick secondary cpus up by SGI 0 interrupt */ - mov x0, xzr /* SGI 0 */ - mov x29, lr /* Save LR */ - bl gic_send_sgi - mov lr, x29 /* Restore LR */ - ret -ENDPROC(smp_kick_all_cpus) diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index bcc2603098..33d3f3688a 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -50,7 +50,10 @@ reset: */ adr x0, vectors switch_el x1, 3f, 2f, 1f -3: msr vbar_el3, x0 +3: mrs x0, scr_el3 + orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */ + msr scr_el3, x0 + msr vbar_el3, x0 msr cptr_el3, xzr /* Enable FP/SIMD */ ldr x0, =COUNTER_FREQUENCY msr cntfrq_el0, x0 /* Initialize CNTFRQ */ @@ -64,10 +67,12 @@ reset: msr cpacr_el1, x0 /* Enable FP/SIMD */ 0: - /* Cache/BPB/TLB Invalidate */ - bl __asm_flush_dcache_all /* dCache clean&invalidate */ - bl __asm_invalidate_icache_all /* iCache invalidate */ - bl __asm_invalidate_tlb_all /* invalidate TLBs */ + /* + * Cache/BPB/TLB Invalidate + * i-cache is invalidated before enabled in icache_enable() + * tlb is invalidated before mmu is enabled in dcache_enable() + * d-cache is invalidated before enabled in dcache_enable() + */ /* Processor specific initialization */ bl lowlevel_init @@ -93,63 +98,64 @@ master_cpu: /*-----------------------------------------------------------------------*/ WEAK(lowlevel_init) - /* Initialize GIC Secure Bank Status */ mov x29, lr /* Save LR */ - bl gic_init - branch_if_master x0, x1, 1f +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) + branch_if_slave x0, 1f + ldr x0, =GICD_BASE + bl gic_init_secure +1: +#if defined(CONFIG_GICV3) + ldr x0, =GICR_BASE + bl gic_init_secure_percpu +#elif defined(CONFIG_GICV2) + ldr x0, =GICD_BASE + ldr x1, =GICC_BASE + bl gic_init_secure_percpu +#endif +#endif + + branch_if_master x0, x1, 2f /* * Slave should wait for master clearing spin table. * This sync prevent salves observing incorrect * value of spin table and jumping to wrong place. */ - bl wait_for_wakeup +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) +#ifdef CONFIG_GICV2 + ldr x0, =GICC_BASE +#endif + bl gic_wait_for_interrupt +#endif /* - * All processors will enter EL2 and optionally EL1. + * All slaves will enter EL2 and optionally EL1. */ bl armv8_switch_to_el2 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1 bl armv8_switch_to_el1 #endif -1: +2: mov lr, x29 /* Restore LR */ ret ENDPROC(lowlevel_init) -/*-----------------------------------------------------------------------*/ - -ENTRY(c_runtime_cpu_setup) - /* If I-cache is enabled invalidate it */ -#ifndef CONFIG_SYS_ICACHE_OFF - ic iallu /* I+BTB cache invalidate */ - isb sy +WEAK(smp_kick_all_cpus) + /* Kick secondary cpus up by SGI 0 interrupt */ + mov x29, lr /* Save LR */ +#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) + ldr x0, =GICD_BASE + bl gic_kick_secondary_cpus #endif + mov lr, x29 /* Restore LR */ + ret +ENDPROC(smp_kick_all_cpus) -#ifndef CONFIG_SYS_DCACHE_OFF - /* - * Setup MAIR and TCR. - */ - ldr x0, =MEMORY_ATTRIBUTES - ldr x1, =TCR_FLAGS - - switch_el x2, 3f, 2f, 1f -3: orr x1, x1, TCR_EL3_IPS_BITS - msr mair_el3, x0 - msr tcr_el3, x1 - b 0f -2: orr x1, x1, TCR_EL2_IPS_BITS - msr mair_el2, x0 - msr tcr_el2, x1 - b 0f -1: orr x1, x1, TCR_EL1_IPS_BITS - msr mair_el1, x0 - msr tcr_el1, x1 -0: -#endif +/*-----------------------------------------------------------------------*/ +ENTRY(c_runtime_cpu_setup) /* Relocate vBAR */ adr x0, vectors switch_el x1, 3f, 2f, 1f diff --git a/arch/arm/cpu/tegra20-common/Makefile b/arch/arm/cpu/tegra20-common/Makefile index 32ddbdae45..0e4b3fc1dd 100644 --- a/arch/arm/cpu/tegra20-common/Makefile +++ b/arch/arm/cpu/tegra20-common/Makefile @@ -9,7 +9,7 @@ # The AVP is ARMv4T architecture so we must use special compiler # flags for any startup files it might use. -CFLAGS_arch/arm/cpu/tegra20-common/warmboot_avp.o += -march=armv4t +CFLAGS_warmboot_avp.o += -march=armv4t obj-y += clock.o funcmux.o pinmux.o obj-$(CONFIG_TEGRA_LP0) += warmboot.o crypto.o warmboot_avp.o diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 87c2de22f5..33c1f99fc0 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -102,6 +102,7 @@ SECTIONS .dynamic : { *(.dynamic*) } .plt : { *(.plt*) } .interp : { *(.interp*) } + .gnu.hash : { *(.gnu.hash) } .gnu : { *(.gnu*) } .ARM.exidx : { *(.ARM.exidx*) } .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) } |