diff options
Diffstat (limited to 'arch/arm')
82 files changed, 1587 insertions, 486 deletions
diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 9a5a9747c4..8f8586295e 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -120,8 +120,8 @@ endif ifdef CONFIG_ARM64 OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn else -OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j \ - .got -j .got.plt -j .u_boot_list -j .rel.dyn +OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \ + -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn endif ifdef CONFIG_OF_EMBED diff --git a/arch/arm/cpu/arm11/cpu.c b/arch/arm/cpu/arm11/cpu.c index 1e4c2142b1..7244c2e7d7 100644 --- a/arch/arm/cpu/arm11/cpu.c +++ b/arch/arm/cpu/arm11/cpu.c @@ -69,23 +69,6 @@ void flush_dcache_all(void) asm volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); } -static int check_cache_range(unsigned long start, unsigned long stop) -{ - int ok = 1; - - if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (!ok) - debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", - start, stop); - - return ok; -} - void invalidate_dcache_range(unsigned long start, unsigned long stop) { if (!check_cache_range(start, stop)) diff --git a/arch/arm/cpu/arm926ejs/cache.c b/arch/arm/cpu/arm926ejs/cache.c index 2839c863e8..2119382ab2 100644 --- a/arch/arm/cpu/arm926ejs/cache.c +++ b/arch/arm/cpu/arm926ejs/cache.c @@ -29,23 +29,6 @@ void flush_dcache_all(void) ); } -static int check_cache_range(unsigned long start, unsigned long stop) -{ - int ok = 1; - - if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (!ok) - debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", - start, stop); - - return ok; -} - void invalidate_dcache_range(unsigned long start, unsigned long stop) { if (!check_cache_range(start, stop)) diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig index afeaac84de..bd6108eec0 100644 --- a/arch/arm/cpu/armv7/Kconfig +++ b/arch/arm/cpu/armv7/Kconfig @@ -21,7 +21,7 @@ config ARMV7_BOOT_SEC_DEFAULT Say Y here to boot in secure mode by default even if non-secure mode is supported. This option is useful to boot kernels which do not suppport booting in non-secure mode. Only set this if you need it. - This can be overriden at run-time by setting the bootm_boot_mode env. + This can be overridden at run-time by setting the bootm_boot_mode env. variable to "sec" or "nonsec". config ARMV7_VIRT diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index ddd8d12d51..0d4bfbc55b 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -19,7 +19,7 @@ endif endif obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o -obj-$(CONFIG_ARMV7_PSCI) += psci.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o obj-$(CONFIG_IPROC) += iproc-common/ obj-$(CONFIG_KONA) += kona-common/ diff --git a/arch/arm/cpu/armv7/am33xx/config.mk b/arch/arm/cpu/armv7/am33xx/config.mk index 6d95d327b4..ab9470820d 100644 --- a/arch/arm/cpu/armv7/am33xx/config.mk +++ b/arch/arm/cpu/armv7/am33xx/config.mk @@ -26,6 +26,7 @@ endif else ifeq ($(CONFIG_TI_SECURE_DEVICE),y) ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER +ALL-y += u-boot_HS.img endif ALL-y += u-boot.img endif diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c index dc309dac90..52f18565db 100644 --- a/arch/arm/cpu/armv7/cache_v7.c +++ b/arch/arm/cpu/armv7/cache_v7.c @@ -19,23 +19,6 @@ void v7_flush_dcache_all(void); void v7_invalidate_dcache_all(void); -static int check_cache_range(unsigned long start, unsigned long stop) -{ - int ok = 1; - - if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) - ok = 0; - - if (!ok) - debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n", - start, stop); - - return ok; -} - static u32 get_ccsidr(void) { u32 ccsidr; @@ -61,27 +44,8 @@ static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len) { u32 mva; - /* - * If start address is not aligned to cache-line do not - * invalidate the first cache-line - */ - if (start & (line_len - 1)) { - printf("ERROR: %s - start address is not aligned - 0x%08x\n", - __func__, start); - /* move to next cache line */ - start = (start + line_len - 1) & ~(line_len - 1); - } - - /* - * If stop address is not aligned to cache-line do not - * invalidate the last cache-line - */ - if (stop & (line_len - 1)) { - printf("ERROR: %s - stop address is not aligned - 0x%08x\n", - __func__, stop); - /* align to the beginning of this cache line */ - stop &= ~(line_len - 1); - } + if (!check_cache_range(start, stop)) + return; for (mva = start; mva < stop; mva = mva + line_len) { /* DCIMVAC - Invalidate data cache by MVA to PoC */ @@ -195,6 +159,14 @@ void flush_dcache_all(void) { } +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + void arm_init_before_mmu(void) { } diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index cf5cd48bcb..f9b26b4321 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -29,16 +29,16 @@ @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - push {lr} + push {r4, r5, r6, lr} @ Clear and Get the correct CPU number @ r1 = 0xf01 - and r1, r1, #0xff + and r4, r1, #0xff - mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + mov r0, r4 + mov r1, r2 + bl psci_save_target_pc + mov r1, r4 @ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) @@ -101,7 +101,7 @@ holdoff_release: @ Return mov r0, #ARM_PSCI_RET_SUCCESS - pop {lr} + pop {r4, r5, r6, lr} bx lr .globl psci_cpu_off @@ -111,16 +111,4 @@ psci_cpu_off: 1: wfi b 1b -.globl psci_arch_init -psci_arch_init: - mov r6, lr - - bl psci_get_cpu_id - bl psci_get_cpu_stack_top - mov sp, r0 - - bx r6 - - .globl psci_text_end -psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c index 9a330476cf..502552d171 100644 --- a/arch/arm/cpu/armv7/mx7/psci-mx7.c +++ b/arch/arm/cpu/armv7/mx7/psci-mx7.c @@ -1,9 +1,9 @@ #include <asm/io.h> #include <asm/psci.h> +#include <asm/secure.h> #include <asm/arch/imx-regs.h> #include <common.h> -#define __secure __attribute__((section("._secure.text"))) #define GPC_CPU_PGC_SW_PDN_REQ 0xfc #define GPC_CPU_PGC_SW_PUP_REQ 0xf0 diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 34c6ab33f0..96e88d6184 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -9,35 +9,22 @@ .arch_extension sec - @ r1 = target CPU - @ r2 = target PC - -.globl psci_arch_init -psci_arch_init: - mov r6, lr - - bl psci_get_cpu_id - bl psci_get_cpu_stack_top - mov sp, r0 - - bx r6 - - @ r1 = target CPU - @ r2 = target PC - .globl psci_cpu_on psci_cpu_on: - push {lr} + push {r4, r5, lr} + mov r4, r0 + mov r5, r1 mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + mov r1, r2 + bl psci_save_target_pc + mov r0, r4 + mov r1, r5 ldr r2, =psci_cpu_entry bl imx_cpu_on - pop {pc} + pop {r4, r5, pc} .globl psci_cpu_off psci_cpu_off: @@ -49,6 +36,4 @@ psci_cpu_off: 1: wfi b 1b - .globl psci_text_end -psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S index b7563edbe6..95ce9387b8 100644 --- a/arch/arm/cpu/armv7/nonsec_virt.S +++ b/arch/arm/cpu/armv7/nonsec_virt.S @@ -49,8 +49,13 @@ _secure_monitor: mcr p15, 0, r5, c12, c0, 1 isb - @ Obtain a secure stack, and configure the PSCI backend + @ Obtain a secure stack + bl psci_stack_setup + + @ Configure the PSCI backend + push {r0, r1, r2, ip} bl psci_arch_init + pop {r0, r1, r2, ip} #endif #ifdef CONFIG_ARM_ERRATA_773022 diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 87a7ac03f9..3172bae105 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -36,3 +36,5 @@ obj-y += boot-common.o obj-y += lowlevel_init.o obj-y += mem-common.o + +obj-$(CONFIG_TI_SECURE_DEVICE) += sec-common.o diff --git a/arch/arm/cpu/armv7/omap-common/config_secure.mk b/arch/arm/cpu/armv7/omap-common/config_secure.mk index c7bb101be8..1122439e38 100644 --- a/arch/arm/cpu/armv7/omap-common/config_secure.mk +++ b/arch/arm/cpu/armv7/omap-common/config_secure.mk @@ -12,8 +12,8 @@ cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \ $(if $(KBUILD_VERBOSE:1=), >/dev/null) else cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \ - $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \ - $(if $(KBUILD_VERBOSE:1=), >/dev/null) + $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) endif else cmd_mkomapsecimg = echo "WARNING:" \ @@ -25,14 +25,33 @@ cmd_mkomapsecimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \ "variable must be defined for TI secure devices. $@ was NOT created!" endif +ifdef CONFIG_SPL_LOAD_FIT +quiet_cmd_omapsecureimg = SECURE $@ +ifneq ($(TI_SECURE_DEV_PKG),) +ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh),) +cmd_omapsecureimg = $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh \ + $< $@ \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) +else +cmd_omapsecureimg = echo "WARNING:" \ + "$(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh not found." \ + "$@ was NOT created!"; cp $< $@ +endif +else +cmd_omapsecureimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \ + "variable must be defined for TI secure devices." \ + "$@ was NOT created!"; cp $< $@ +endif +endif + + # Standard X-LOADER target (QPSI, NOR flash) u-boot-spl_HS_X-LOADER: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) -# For MLO targets (SD card boot) the final file name -# that is copied to the SD card fAT partition must -# be MLO, so we make a copy of the output file to a -# new file with that name +# For MLO targets (SD card boot) the final file name that is copied to the SD +# card FAT partition must be MLO, so we make a copy of the output file to a new +# file with that name u-boot-spl_HS_MLO: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) @if [ -f $@ ]; then \ @@ -51,16 +70,44 @@ u-boot-spl_HS_ULO: $(obj)/u-boot-spl.bin u-boot-spl_HS_ISSW: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) -# For SPI flash on AM335x and AM43xx, these -# require special byte swap handling so we use -# the SPI_X-LOADER target instead of X-LOADER -# and let the create-boot-image.sh script handle -# that +# For SPI flash on AM335x and AM43xx, these require special byte swap handling +# so we use the SPI_X-LOADER target instead of X-LOADER and let the +# create-boot-image.sh script handle that u-boot-spl_HS_SPI_X-LOADER: $(obj)/u-boot-spl.bin $(call if_changed,mkomapsecimg) -# For supporting single stage XiP QSPI on AM43xx, the -# image is a full u-boot file, not an SPL. In this case -# the mkomapsecimg command looks for a u-boot-HS_* prefix +# For supporting single stage XiP QSPI on AM43xx, the image is a full u-boot +# file, not an SPL. In this case the mkomapsecimg command looks for a +# u-boot-HS_* prefix u-boot_HS_XIP_X-LOADER: $(obj)/u-boot.bin $(call if_changed,mkomapsecimg) + +# For supporting the SPL loading and interpreting of FIT images whose +# components are pre-processed before being integrated into the FIT image in +# order to secure them in some way +ifdef CONFIG_SPL_LOAD_FIT + +MKIMAGEFLAGS_u-boot_HS.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \ + -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \ + $(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) + +OF_LIST_TARGETS = $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) +$(OF_LIST_TARGETS): dtbs + +%_HS.dtb: %.dtb + $(call if_changed,omapsecureimg) + $(Q)if [ -f $@ ]; then \ + cp -f $@ $<; \ + fi + +u-boot-nodtb_HS.bin: u-boot-nodtb.bin + $(call if_changed,omapsecureimg) + +u-boot_HS.img: u-boot-nodtb_HS.bin u-boot.img $(patsubst %.dtb,%_HS.dtb,$(OF_LIST_TARGETS)) + $(call if_changed,mkimage) + $(Q)if [ -f $@ ]; then \ + cp -f $@ u-boot.img; \ + fi + +endif diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index 9a9c764b4d..2b790105b0 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -37,7 +37,8 @@ void set_lpmode_selfrefresh(u32 base) void force_emif_self_refresh() { set_lpmode_selfrefresh(EMIF1_BASE); - set_lpmode_selfrefresh(EMIF2_BASE); + if (!is_dra72x()) + set_lpmode_selfrefresh(EMIF2_BASE); } inline u32 emif_num(u32 base) diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 2f9693f28e..f317293988 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -147,8 +147,7 @@ void early_system_init(void) hw_data_init(); #ifdef CONFIG_SPL_BUILD - if (warm_reset() && - (is_omap44xx() || (omap_revision() == OMAP5430_ES1_0))) + if (warm_reset()) force_emif_self_refresh(); #endif watchdog_init(); diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 528313584f..66a3b3d26c 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -16,9 +16,10 @@ #include <asm/arch/spl.h> #include <linux/linkage.h> +.arch_extension sec + #ifdef CONFIG_SPL ENTRY(save_boot_params) - ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS str r0, [r1] b save_boot_params_ret @@ -26,14 +27,40 @@ ENDPROC(save_boot_params) #endif ENTRY(omap_smc1) - PUSH {r4-r12, lr} @ save registers - ROM code may pollute + push {r4-r12, lr} @ save registers - ROM code may pollute @ our registers - MOV r12, r0 @ Service - MOV r0, r1 @ Argument - DSB - DMB - .word 0xe1600070 @ SMC #0 - hand assembled for GCC versions - @ call ROM Code API for the service requested + mov r12, r0 @ Service + mov r0, r1 @ Argument - POP {r4-r12, pc} + dsb + dmb + smc 0 @ SMC #0 to enter monitor mode + @ call ROM Code API for the service requested + pop {r4-r12, pc} ENDPROC(omap_smc1) + +ENTRY(omap_smc_sec) + push {r4-r12, lr} @ save registers - ROM code may pollute + @ our registers + mov r6, #0xFF @ Indicate new Task call + mov r12, #0x00 @ Secure Service ID in R12 + + dsb + dmb + smc 0 @ SMC #0 to enter monitor mode + + b omap_smc_sec_end @ exit at end of the service execution + nop + + @ In case of IRQ happening in Secure, then ARM will branch here. + @ At that moment, IRQ will be pending and ARM will jump to Non Secure + @ IRQ handler + mov r12, #0xFE + + dsb + dmb + smc 0 @ SMC #0 to enter monitor mode + +omap_smc_sec_end: + pop {r4-r12, pc} +ENDPROC(omap_smc_sec) diff --git a/arch/arm/cpu/armv7/omap-common/sec-common.c b/arch/arm/cpu/armv7/omap-common/sec-common.c new file mode 100644 index 0000000000..246a2393da --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/sec-common.c @@ -0,0 +1,139 @@ +/* + * + * Common security related functions for OMAP devices + * + * (C) Copyright 2016 + * Texas Instruments, <www.ti.com> + * + * Daniel Allred <d-allred@ti.com> + * Andreas Dannenberg <dannenberg@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <stdarg.h> + +#include <asm/arch/sys_proto.h> +#include <asm/omap_common.h> +#include <asm/omap_sec_common.h> +#include <asm/spl.h> +#include <spl.h> + +/* Index for signature verify ROM API */ +#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX (0x0000000E) + +static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN); + +u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...) +{ + int i; + u32 num_args; + va_list ap; + + va_start(ap, flag); + + num_args = va_arg(ap, u32); + + if (num_args > 4) + return 1; + + /* Copy args to aligned args structure */ + for (i = 0; i < num_args; i++) + secure_rom_call_args[i + 1] = va_arg(ap, u32); + + secure_rom_call_args[0] = num_args; + + va_end(ap); + + /* if data cache is enabled, flush the aligned args structure */ + flush_dcache_range( + (unsigned int)&secure_rom_call_args[0], + (unsigned int)&secure_rom_call_args[0] + + roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN)); + + return omap_smc_sec(service, proc_id, flag, secure_rom_call_args); +} + +static u32 find_sig_start(char *image, size_t size) +{ + char *image_end = image + size; + char *sig_start_magic = "CERT_"; + int magic_str_len = strlen(sig_start_magic); + char *ch; + + while (--image_end > image) { + if (*image_end == '_') { + ch = image_end - magic_str_len + 1; + if (!strncmp(ch, sig_start_magic, magic_str_len)) + return (u32)ch; + } + } + return 0; +} + +int secure_boot_verify_image(void **image, size_t *size) +{ + int result = 1; + u32 cert_addr, sig_addr; + size_t cert_size; + + /* Perform cache writeback on input buffer */ + flush_dcache_range( + (u32)*image, + (u32)*image + roundup(*size, ARCH_DMA_MINALIGN)); + + cert_addr = (uint32_t)*image; + sig_addr = find_sig_start((char *)*image, *size); + + if (sig_addr == 0) { + printf("No signature found in image!\n"); + result = 1; + goto auth_exit; + } + + *size = sig_addr - cert_addr; /* Subtract out the signature size */ + cert_size = *size; + + /* Check if image load address is 32-bit aligned */ + if (!IS_ALIGNED(cert_addr, 4)) { + printf("Image is not 4-byte aligned!\n"); + result = 1; + goto auth_exit; + } + + /* Image size also should be multiple of 4 */ + if (!IS_ALIGNED(cert_size, 4)) { + printf("Image size is not 4-byte aligned!\n"); + result = 1; + goto auth_exit; + } + + /* Call ROM HAL API to verify certificate signature */ + debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__, + cert_addr, cert_size, sig_addr); + + result = secure_rom_call( + API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0, + 4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF); +auth_exit: + if (result != 0) { + printf("Authentication failed!\n"); + printf("Return Value = %08X\n", result); + hang(); + } + + /* + * Output notification of successful authentication as well the name of + * the signing certificate used to re-assure the user that the secure + * code is being processed as expected. However suppress any such log + * output in case of building for SPL and booting via YMODEM. This is + * done to avoid disturbing the YMODEM serial protocol transactions. + */ + if (!(IS_ENABLED(CONFIG_SPL_BUILD) && + IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) && + spl_boot_device() == BOOT_DEVICE_UART)) + printf("Authentication passed: %s\n", (char *)sig_addr); + + return result; +} diff --git a/arch/arm/cpu/armv7/omap5/config.mk b/arch/arm/cpu/armv7/omap5/config.mk index a7e55a5e24..d245572ef0 100644 --- a/arch/arm/cpu/armv7/omap5/config.mk +++ b/arch/arm/cpu/armv7/omap5/config.mk @@ -15,5 +15,8 @@ else ALL-y += MLO endif else +ifeq ($(CONFIG_TI_SECURE_DEVICE),y) +ALL-y += u-boot_HS.img +endif ALL-y += u-boot.img endif diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 0000000000..d14b693747 --- /dev/null +++ b/arch/arm/cpu/armv7/psci-common.c @@ -0,0 +1,39 @@ +/* + * Common PSCI functions + * + * Copyright (C) 2016 Chen-Yu Tsai + * Author: Chen-Yu Tsai <wens@csie.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <asm/armv7.h> +#include <asm/macro.h> +#include <asm/psci.h> +#include <asm/secure.h> +#include <linux/linkage.h> + +static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 }; + +void __secure psci_save_target_pc(int cpu, u32 pc) +{ + psci_target_pc[cpu] = pc; + DSB; +} + +u32 __secure psci_get_target_pc(int cpu) +{ + return psci_target_pc[cpu]; +} + diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index ab408378fc..350b75ce20 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -196,29 +196,56 @@ ENTRY(psci_cpu_off_common) bx lr ENDPROC(psci_cpu_off_common) -@ expects CPU ID in r0 and returns stack top in r0 -ENTRY(psci_get_cpu_stack_top) - mov r3, #0x400 @ 1kB of stack per CPU - mul r0, r0, r3 - - ldr r3, =psci_text_end @ end of monitor text - add r3, r3, #0x2000 @ Skip two pages - lsr r3, r3, #12 @ Align to start of page - lsl r3, r3, #12 - sub r3, r3, #4 @ reserve 1 word for target PC - sub r0, r3, r0 @ here's our stack! - +@ The stacks are allocated in reverse order, i.e. +@ the stack for CPU0 has the highest memory address. +@ +@ -------------------- __secure_stack_end +@ | CPU0 target PC | +@ |------------------| +@ | | +@ | CPU0 stack | +@ | | +@ |------------------| __secure_stack_end - 1KB +@ | . | +@ | . | +@ | . | +@ | . | +@ -------------------- __secure_stack_start +@ +@ This expects CPU ID in r0 and returns stack top in r0 +LENTRY(psci_get_cpu_stack_top) + @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT) + ldr r3, =__secure_stack_end + sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT + sub r0, r0, #4 @ Save space for target PC bx lr ENDPROC(psci_get_cpu_stack_top) +@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in +@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across +@ this function. +ENTRY(psci_stack_setup) + mov r6, lr + mov r7, r0 + bl psci_get_cpu_id @ CPU ID => r0 + bl psci_get_cpu_stack_top @ stack top => r0 + mov sp, r0 + mov r0, r7 + bx r6 +ENDPROC(psci_stack_setup) + +ENTRY(psci_arch_init) + mov pc, lr +ENDPROC(psci_arch_init) +.weak psci_arch_init + ENTRY(psci_cpu_entry) bl psci_enable_smp bl _nonsec_init bl psci_get_cpu_id @ CPU ID => r0 - bl psci_get_cpu_stack_top @ stack top => r0 - ldr r0, [r0] @ target PC at stack top + bl psci_get_target_pc @ target PC => r0 b _do_nonsec_entry ENDPROC(psci_cpu_entry) diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index c208510168..b35b9df4a9 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMV7_PSCI) += psci.o -obj-$(CONFIG_ARMV7_PSCI) += psci_head.o endif ifdef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index a118e9d0c4..7ac84065f4 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -17,11 +17,11 @@ #include <asm/gic.h> #include <asm/io.h> #include <asm/psci.h> +#include <asm/secure.h> #include <asm/system.h> #include <linux/bitops.h> -#define __secure __attribute__ ((section ("._secure.text"))) #define __irq __attribute__ ((interrupt ("IRQ"))) #define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET) @@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc) (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; u32 cpu = (mpidr & 0x3); - /* store target PC at target CPU stack top */ - writel(pc, psci_get_cpu_stack_top(cpu)); - DSB; + /* store target PC */ + psci_save_target_pc(cpu, pc); /* Set secondary core power on PC */ writel((u32)&psci_cpu_entry, &cpucfg->priv0); @@ -250,7 +249,7 @@ void __secure psci_cpu_off(void) wfi(); } -void __secure sunxi_gic_init(void) +void __secure psci_arch_init(void) { u32 reg; diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S deleted file mode 100644 index 8fa823d1df..0000000000 --- a/arch/arm/cpu/armv7/sunxi/psci_head.S +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2013 - ARM Ltd - * Author: Marc Zyngier <marc.zyngier@arm.com> - * - * Based on code by Carl van Schaik <carl@ok-labs.com>. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include <config.h> -#include <linux/linkage.h> - -#include <asm/arch-armv7/generictimer.h> -#include <asm/gic.h> -#include <asm/macro.h> -#include <asm/psci.h> -#include <asm/arch/cpu.h> - -/* - * Memory layout: - * - * SECURE_RAM to text_end : - * ._secure_text section - * text_end to ALIGN_PAGE(text_end): - * nothing - * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000) - * 1kB of stack per CPU (4 CPUs max). - */ - - .pushsection ._secure.text, "ax" - - .arch_extension sec - -#define GICD_BASE (SUNXI_GIC400_BASE + 0x1000) -#define GICC_BASE (SUNXI_GIC400_BASE + 0x2000) - -@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in -@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across -@ this function. -ENTRY(psci_arch_init) - mov r6, lr - mov r7, r0 - bl psci_get_cpu_id @ CPU ID => r0 - bl psci_get_cpu_stack_top @ stack top => r0 - sub r0, r0, #4 @ Save space for target PC - mov sp, r0 - mov r0, r7 - mov lr, r6 - - push {r0, r1, r2, ip, lr} - bl sunxi_gic_init - pop {r0, r1, r2, ip, pc} -ENDPROC(psci_arch_init) - -ENTRY(psci_text_end) - .popsection diff --git a/arch/arm/cpu/armv7m/config.mk b/arch/arm/cpu/armv7m/config.mk index 4a53006b6a..db4660e15d 100644 --- a/arch/arm/cpu/armv7m/config.mk +++ b/arch/arm/cpu/armv7m/config.mk @@ -5,4 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -PLATFORM_CPPFLAGS += -march=armv7-m -mthumb +PLATFORM_CPPFLAGS += -march=armv7-m -mthumb -mno-unaligned-access diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index 3d19bbfbe2..acf2460ede 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -3,4 +3,22 @@ if ARM64 config ARMV8_MULTIENTRY boolean "Enable multiple CPUs to enter into U-Boot" +config ARMV8_SPIN_TABLE + bool "Support spin-table enable method" + depends on ARMV8_MULTIENTRY && OF_LIBFDT + help + Say Y here to support "spin-table" enable method for booting Linux. + + To use this feature, you must do: + - Specify enable-method = "spin-table" in each CPU node in the + Device Tree you are using to boot the kernel + - Let secondary CPUs in U-Boot (in a board specific manner) + before the master CPU jumps to the kernel + + U-Boot automatically does: + - Set "cpu-release-addr" property of each CPU node + (overwrites it if already exists). + - Reserve the code for the spin-table and the release address + via a /memreserve/ region in the Device Tree. + endif diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index 33e6db0cc5..dea14657d9 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -16,6 +16,9 @@ obj-y += tlb.o obj-y += transition.o obj-y += fwcall.o obj-y += cpu-dt.o +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o +endif obj-$(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/ diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 index da5e052569..7867c379d4 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 +++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.lsch3 @@ -128,7 +128,7 @@ mcinitcmd: This environment variable is defined to initiate MC and DPL deploymen during U-boot booting.However the MC, DPC and DPL can be applied from console independently. The variable needs to be set from the console once and then on - rebooting the parameters set in the varible will automatically be + rebooting the parameters set in the variable will automatically be executed. The commmand is demostrated taking an example of mc boot using NOR Flash i.e. MC, DPL, and DPC is stored in the NOR flash: diff --git a/arch/arm/cpu/armv8/spin_table.c b/arch/arm/cpu/armv8/spin_table.c new file mode 100644 index 0000000000..ec1c9b8ddb --- /dev/null +++ b/arch/arm/cpu/armv8/spin_table.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <libfdt.h> +#include <asm/spin_table.h> + +int spin_table_update_dt(void *fdt) +{ + int cpus_offset, offset; + const char *prop; + int ret; + unsigned long rsv_addr = (unsigned long)&spin_table_reserve_begin; + unsigned long rsv_size = &spin_table_reserve_end - + &spin_table_reserve_begin; + + cpus_offset = fdt_path_offset(fdt, "/cpus"); + if (cpus_offset < 0) + return -ENODEV; + + for (offset = fdt_first_subnode(fdt, cpus_offset); + offset >= 0; + offset = fdt_next_subnode(fdt, offset)) { + prop = fdt_getprop(fdt, offset, "device_type", NULL); + if (!prop || strcmp(prop, "cpu")) + continue; + + /* + * In the first loop, we check if every CPU node specifies + * spin-table. Otherwise, just return successfully to not + * disturb other methods, like psci. + */ + prop = fdt_getprop(fdt, offset, "enable-method", NULL); + if (!prop || strcmp(prop, "spin-table")) + return 0; + } + + for (offset = fdt_first_subnode(fdt, cpus_offset); + offset >= 0; + offset = fdt_next_subnode(fdt, offset)) { + prop = fdt_getprop(fdt, offset, "device_type", NULL); + if (!prop || strcmp(prop, "cpu")) + continue; + + ret = fdt_setprop_u64(fdt, offset, "cpu-release-addr", + (unsigned long)&spin_table_cpu_release_addr); + if (ret) + return -ENOSPC; + } + + ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size); + if (ret) + return -ENOSPC; + + printf(" Reserved memory region for spin-table: addr=%lx size=%lx\n", + rsv_addr, rsv_size); + + return 0; +} diff --git a/arch/arm/cpu/armv8/spin_table_v8.S b/arch/arm/cpu/armv8/spin_table_v8.S new file mode 100644 index 0000000000..d7f78a6a67 --- /dev/null +++ b/arch/arm/cpu/armv8/spin_table_v8.S @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/linkage.h> + +ENTRY(spin_table_secondary_jump) +.globl spin_table_reserve_begin +spin_table_reserve_begin: +0: wfe + ldr x0, spin_table_cpu_release_addr + cbz x0, 0b + br x0 +.globl spin_table_cpu_release_addr + .align 3 +spin_table_cpu_release_addr: + .quad 0 +.globl spin_table_reserve_end +spin_table_reserve_end: +ENDPROC(spin_table_secondary_jump) diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 670e323b61..67edf94520 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -94,7 +94,11 @@ reset: /* Processor specific initialization */ bl lowlevel_init -#ifdef CONFIG_ARMV8_MULTIENTRY +#if CONFIG_IS_ENABLED(ARMV8_SPIN_TABLE) + branch_if_master x0, x1, master_cpu + b spin_table_secondary_jump + /* never return */ +#elif defined(CONFIG_ARMV8_MULTIENTRY) branch_if_master x0, x1, master_cpu /* @@ -106,10 +110,8 @@ slave_cpu: ldr x0, [x1] cbz x0, slave_cpu br x0 /* branch to the given address */ -master_cpu: - /* On the master CPU */ #endif /* CONFIG_ARMV8_MULTIENTRY */ - +master_cpu: bl _main #ifdef CONFIG_SYS_RESET_SCTRL diff --git a/arch/arm/cpu/armv8/zynqmp/mp.c b/arch/arm/cpu/armv8/zynqmp/mp.c index 58312a79bc..e10fc3136c 100644 --- a/arch/arm/cpu/armv8/zynqmp/mp.c +++ b/arch/arm/cpu/armv8/zynqmp/mp.c @@ -128,7 +128,7 @@ static void enable_clock_r5(void) writel(tmp, &crlapb_base->cpu_r5_ctrl); /* Give some delay for clock - * to propogate */ + * to propagate */ udelay(0x500); } diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 1769b6ea88..36c9fd0bd0 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -8,6 +8,7 @@ */ #include <config.h> +#include <asm/psci.h> OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) @@ -48,34 +49,67 @@ SECTIONS #ifdef CONFIG_ARMV7_NONSEC + /* Align the secure section only if we're going to use it in situ */ + .__secure_start : +#ifndef CONFIG_ARMV7_SECURE_BASE + ALIGN(CONSTANT(COMMONPAGESIZE)) +#endif + { + KEEP(*(.__secure_start)) + } + #ifndef CONFIG_ARMV7_SECURE_BASE #define CONFIG_ARMV7_SECURE_BASE #define __ARMV7_PSCI_STACK_IN_RAM #endif - .__secure_start : { - . = ALIGN(0x1000); - *(.__secure_start) - } - .secure_text CONFIG_ARMV7_SECURE_BASE : AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) { *(._secure.text) } - . = LOADADDR(.__secure_start) + - SIZEOF(.__secure_start) + - SIZEOF(.secure_text); + .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) + { + *(._secure.data) + } + .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data), + CONSTANT(COMMONPAGESIZE)) (NOLOAD) : #ifdef __ARMV7_PSCI_STACK_IN_RAM - /* Align to page boundary and skip 2 pages */ - . = (. & ~ 0xfff) + 0x2000; -#undef __ARMV7_PSCI_STACK_IN_RAM + AT(ADDR(.secure_stack)) +#else + AT(LOADADDR(.secure_data) + SIZEOF(.secure_data)) +#endif + { + KEEP(*(.__secure_stack_start)) + + /* Skip addreses for stack */ + . = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE; + + /* Align end of stack section to page boundary */ + . = ALIGN(CONSTANT(COMMONPAGESIZE)); + + KEEP(*(.__secure_stack_end)) + +#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE + /* + * We are not checking (__secure_end - __secure_start) here, + * as these are the load addresses, and do not include the + * stack section. Instead, use the end of the stack section + * and the start of the text section. + */ + ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE, + "Error: secure section exceeds secure memory size"); +#endif + } + +#ifndef __ARMV7_PSCI_STACK_IN_RAM + /* Reset VMA but don't allocate space if we have secure SRAM */ + . = LOADADDR(.secure_stack); #endif - __secure_end_lma = .; - .__secure_end : AT(__secure_end_lma) { + .__secure_end : AT(ADDR(.__secure_end)) { *(.__secure_end) LONG(0x1d1071c); /* Must output something to reset LMA */ } diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index ef573ec685..acecb7c359 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -242,6 +242,7 @@ dtb-$(CONFIG_MACH_SUN8I_A83T) += \ sun8i-a83t-sinovoip-bpi-m3.dtb dtb-$(CONFIG_MACH_SUN8I_H3) += \ sun8i-h3-orangepi-2.dtb \ + sun8i-h3-orangepi-lite.dtb \ sun8i-h3-orangepi-one.dtb \ sun8i-h3-orangepi-pc.dtb \ sun8i-h3-orangepi-plus.dtb diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts index 3f87761584..26c4d7f4c6 100644 --- a/arch/arm/dts/exynos4210-origen.dts +++ b/arch/arm/dts/exynos4210-origen.dts @@ -22,7 +22,7 @@ aliases { serial0 = "/serial@13800000"; console = "/serial@13820000"; - mmc2 = "sdhci@12530000"; + mmc2 = "/sdhci@12530000"; }; sdhci@12510000 { diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts index f3fac80190..2ed38f369e 100644 --- a/arch/arm/dts/exynos4210-trats.dts +++ b/arch/arm/dts/exynos4210-trats.dts @@ -29,8 +29,8 @@ i2c7 = "/i2c@138d0000"; serial0 = "/serial@13800000"; console = "/serial@13820000"; - mmc0 = "sdhci@12510000"; - mmc2 = "sdhci@12530000"; + mmc0 = "/sdhci@12510000"; + mmc2 = "/sdhci@12530000"; }; fimd@11c00000 { diff --git a/arch/arm/dts/exynos4210-universal_c210.dts b/arch/arm/dts/exynos4210-universal_c210.dts index ad3527ec6f..8cac7dd752 100644 --- a/arch/arm/dts/exynos4210-universal_c210.dts +++ b/arch/arm/dts/exynos4210-universal_c210.dts @@ -17,8 +17,8 @@ aliases { serial0 = "/serial@13800000"; console = "/serial@13820000"; - mmc0 = "sdhci@12510000"; - mmc2 = "sdhci@12530000"; + mmc0 = "/sdhci@12510000"; + mmc2 = "/sdhci@12530000"; }; sdhci@12510000 { diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index a63e8abab4..188cb939bb 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -25,8 +25,8 @@ i2c7 = "/i2c@138d0000"; serial0 = "/serial@13800000"; console = "/serial@13810000"; - mmc2 = "sdhci@12530000"; - mmc4 = "dwmmc@12550000"; + mmc2 = "/sdhci@12530000"; + mmc4 = "/dwmmc@12550000"; }; i2c@13860000 { diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts index 2d4e522ea2..1fbcf8914f 100644 --- a/arch/arm/dts/exynos4412-trats2.dts +++ b/arch/arm/dts/exynos4412-trats2.dts @@ -29,9 +29,9 @@ i2c7 = "/i2c@138d0000"; serial0 = "/serial@13800000"; console = "/serial@13820000"; - mmc0 = "sdhci@12510000"; - mmc2 = "sdhci@12530000"; - mmc4 = "dwmmc@12550000"; + mmc0 = "/sdhci@12510000"; + mmc2 = "/sdhci@12530000"; + mshc0 = "/dwmmc@12550000"; }; i2c@138d0000 { diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts index aed8d3a712..3176d5046b 100644 --- a/arch/arm/dts/rk3288-firefly.dts +++ b/arch/arm/dts/rk3288-firefly.dts @@ -30,7 +30,8 @@ 0x5 0x0>; rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200 0xa60 0x40 0x10 0x0>; - rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf>; + /* Add a dummy value to cause of-platdata think this is bytes */ + rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>; rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>; }; diff --git a/arch/arm/dts/sun50i-a64-pine64-plus.dts b/arch/arm/dts/sun50i-a64-pine64-plus.dts index 549dc15bd5..389c6096ca 100644 --- a/arch/arm/dts/sun50i-a64-pine64-plus.dts +++ b/arch/arm/dts/sun50i-a64-pine64-plus.dts @@ -57,3 +57,16 @@ reg = <0x40000000 0x40000000>; }; }; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + phy-mode = "rgmii"; + phy = <&phy1>; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + diff --git a/arch/arm/dts/sun50i-a64.dtsi b/arch/arm/dts/sun50i-a64.dtsi index 1bd436f847..7d0dc76a11 100644 --- a/arch/arm/dts/sun50i-a64.dtsi +++ b/arch/arm/dts/sun50i-a64.dtsi @@ -506,6 +506,25 @@ allwinner,drive = <SUN4I_PINCTRL_10_MA>; allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; }; + + rmii_pins: rmii_pins { + allwinner,pins = "PD10", "PD11", "PD13", "PD14", + "PD17", "PD18", "PD19", "PD20", + "PD22", "PD23"; + allwinner,function = "emac"; + allwinner,drive = <SUN4I_PINCTRL_40_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + rgmii_pins: rgmii_pins { + allwinner,pins = "PD8", "PD9", "PD10", "PD11", + "PD12", "PD13", "PD15", + "PD16", "PD17", "PD18", "PD19", + "PD20", "PD21", "PD22", "PD23"; + allwinner,function = "emac"; + allwinner,drive = <SUN4I_PINCTRL_40_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; }; ahb_rst: reset@1c202c0 { @@ -620,5 +639,19 @@ #address-cells = <1>; #size-cells = <0>; }; + + emac: ethernet@01c30000 { + compatible = "allwinner,sun50i-a64-emac"; + reg = <0x01c30000 0x2000>, <0x01c00030 0x4>; + reg-names = "emac", "syscon"; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + resets = <&ahb_rst 17>; + reset-names = "ahb"; + clocks = <&bus_gates 17>; + clock-names = "ahb"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; }; }; diff --git a/arch/arm/dts/sun8i-h3-orangepi-2.dts b/arch/arm/dts/sun8i-h3-orangepi-2.dts index f93f5d1695..d3f8f550a2 100644 --- a/arch/arm/dts/sun8i-h3-orangepi-2.dts +++ b/arch/arm/dts/sun8i-h3-orangepi-2.dts @@ -184,3 +184,16 @@ usb1_vbus-supply = <®_usb1_vbus>; status = "okay"; }; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + phy-mode = "rgmii"; + phy = <&phy1>; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + diff --git a/arch/arm/dts/sun8i-h3-orangepi-lite.dts b/arch/arm/dts/sun8i-h3-orangepi-lite.dts new file mode 100644 index 0000000000..ac7174914e --- /dev/null +++ b/arch/arm/dts/sun8i-h3-orangepi-lite.dts @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2016 Hans de Goede <hdegoede@redhat.com> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-h3.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/pinctrl/sun4i-a10.h> + +/ { + model = "Xunlong Orange Pi Lite"; + compatible = "xunlong,orangepi-lite", "allwinner,sun8i-h3"; + + aliases { + /* The H3 emac is not used so the wifi is ethernet0 */ + ethernet1 = &rtl8189ftv; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&leds_opc>, <&leds_r_opc>; + + pwr_led { + label = "orangepi:green:pwr"; + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + status_led { + label = "orangepi:red:status"; + gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>; + }; + }; + + r_gpio_keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&sw_r_opc>; + + sw4 { + label = "sw4"; + linux,code = <BTN_0>; + gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ir { + pinctrl-names = "default"; + pinctrl-0 = <&ir_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_a>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + non-removable; + status = "okay"; + + /* + * Explicitly define the sdio device, so that we can add an ethernet + * alias for it (which e.g. makes u-boot set a mac-address). + */ + rtl8189ftv: sdio_wifi@1 { + reg = <1>; + }; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; + +&pio { + leds_opc: led_pins@0 { + allwinner,pins = "PA15"; + allwinner,function = "gpio_out"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; +}; + +&r_pio { + leds_r_opc: led_pins@0 { + allwinner,pins = "PL10"; + allwinner,function = "gpio_out"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + sw_r_opc: key_pins@0 { + allwinner,pins = "PL3"; + allwinner,function = "gpio_in"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + /* USB VBUS is always on */ + status = "okay"; +}; diff --git a/arch/arm/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/dts/sun8i-h3-orangepi-pc.dts index 30ccca019d..0a74a9193b 100644 --- a/arch/arm/dts/sun8i-h3-orangepi-pc.dts +++ b/arch/arm/dts/sun8i-h3-orangepi-pc.dts @@ -173,3 +173,15 @@ /* USB VBUS is always on */ status = "okay"; }; + +&emac { + phy = <&phy1>; + phy-mode = "mii"; + allwinner,use-internal-phy; + allwinner,leds-active-low; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; diff --git a/arch/arm/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/dts/sun8i-h3-orangepi-plus.dts index 900ec4fc8c..28f74f6ffd 100644 --- a/arch/arm/dts/sun8i-h3-orangepi-plus.dts +++ b/arch/arm/dts/sun8i-h3-orangepi-plus.dts @@ -40,26 +40,13 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/dts-v1/; -#include "sun8i-h3.dtsi" -#include "sunxi-common-regulators.dtsi" - -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/input/input.h> -#include <dt-bindings/pinctrl/sun4i-a10.h> +/* The Orange Pi Plus is an extended version of the Orange Pi 2 */ +#include "sun8i-h3-orangepi-2.dts" / { - model = "Xunlong Orange Pi Plus"; + model = "Xunlong Orange Pi Plus / Plus 2 / Plus 2E"; compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3"; - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - reg_usb3_vbus: usb3-vbus { compatible = "regulator-fixed"; pinctrl-names = "default"; @@ -71,75 +58,42 @@ enable-active-high; gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; }; +}; - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&leds_opc>; - - status_led { - label = "status:red:user"; - gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>; - }; - }; - - r_leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&leds_r_opc>; - - tx { - label = "pwr:green:user"; - gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - }; - - r_gpio_keys { - compatible = "gpio-keys"; - input-name = "sw4"; - - pinctrl-names = "default"; - pinctrl-0 = <&sw_r_opc>; +&ehci2 { + status = "okay"; +}; - sw4@0 { - label = "sw4"; - linux,code = <BTN_0>; - gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; - }; - }; +&ehci3 { + status = "okay"; }; -&pio { - leds_opc: led_pins@0 { - allwinner,pins = "PA15"; - allwinner,function = "gpio_out"; - allwinner,drive = <SUN4I_PINCTRL_10_MA>; - allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; - }; +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; }; -&r_pio { - leds_r_opc: led_pins@0 { - allwinner,pins = "PL10"; - allwinner,function = "gpio_out"; - allwinner,drive = <SUN4I_PINCTRL_10_MA>; - allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; - }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = <SUN4I_PINCTRL_40_MA>; + /* eMMC is missing pull-ups */ + allwinner,pull = <SUN4I_PINCTRL_PULL_UP>; +}; - sw_r_opc: key_pins@0 { - allwinner,pins = "PL03"; - allwinner,function = "gpio_in"; - allwinner,drive = <SUN4I_PINCTRL_10_MA>; - allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; - }; +&ohci1 { + status = "okay"; }; -&ehci1 { +&ohci2 { status = "okay"; }; -&ehci3 { +&ohci3 { status = "okay"; }; @@ -152,33 +106,6 @@ }; }; -&mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; - vmmc-supply = <®_vcc3v3>; - bus-width = <4>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ - cd-inverted; - status = "okay"; -}; - -®_usb1_vbus { - gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>; - status = "okay"; -}; - -&uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; -}; - -&usb1_vbus_pin_a { - allwinner,pins = "PG13"; -}; - &usbphy { - usb1_vbus-supply = <®_usb1_vbus>; usb3_vbus-supply = <®_usb3_vbus>; - status = "okay"; }; diff --git a/arch/arm/dts/sun8i-h3.dtsi b/arch/arm/dts/sun8i-h3.dtsi index c2f63c5050..72c0920466 100644 --- a/arch/arm/dts/sun8i-h3.dtsi +++ b/arch/arm/dts/sun8i-h3.dtsi @@ -501,6 +501,17 @@ interrupt-controller; #interrupt-cells = <3>; + rgmii_pins: rgmii_pins { + allwinner,pins = "PD0", "PD1", "PD2", "PD3", + "PD4", "PD5", "PD7", + "PD8", "PD9", "PD10", + "PD12", "PD13", "PD15", + "PD16", "PD17"; + allwinner,function = "emac"; + allwinner,drive = <SUN4I_PINCTRL_40_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + uart0_pins_a: uart0@0 { allwinner,pins = "PA4", "PA5"; allwinner,function = "uart0"; @@ -530,6 +541,16 @@ allwinner,drive = <SUN4I_PINCTRL_30_MA>; allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; }; + + mmc2_8bit_pins: mmc2_8bit { + allwinner,pins = "PC5", "PC6", "PC8", + "PC9", "PC10", "PC11", + "PC12", "PC13", "PC14", + "PC15", "PC16"; + allwinner,function = "mmc2"; + allwinner,drive = <SUN4I_PINCTRL_30_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; }; ahb_rst: reset@01c202c0 { @@ -616,6 +637,20 @@ status = "disabled"; }; + emac: ethernet@01c30000 { + compatible = "allwinner,sun8i-h3-emac"; + reg = <0x01c30000 0x2000>, <0x01c00030 0x4>; + reg-names = "emac", "syscon"; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + resets = <&ahb_rst 17>, <&ahb_rst 66>; + reset-names = "ahb", "ephy"; + clocks = <&bus_gates 17>, <&bus_gates 128>; + clock-names = "ahb", "ephy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + gic: interrupt-controller@01c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, diff --git a/arch/arm/imx-common/ddrmc-vf610.c b/arch/arm/imx-common/ddrmc-vf610.c index daf3c7ebfa..9bc56f6ac1 100644 --- a/arch/arm/imx-common/ddrmc-vf610.c +++ b/arch/arm/imx-common/ddrmc-vf610.c @@ -212,7 +212,7 @@ void ddrmc_ctrl_init_ddr3(struct ddr3_jedec_timings const *timings, cr_setting++; } - /* perform default PHY settings (may be overriden by custom settings */ + /* perform default PHY settings (may be overridden by custom settings */ phy_setting = default_phy_settings; while (phy_setting->phy_rnum >= 0) { writel(phy_setting->setting, diff --git a/arch/arm/include/asm/arch-rockchip/sdram.h b/arch/arm/include/asm/arch-rockchip/sdram.h index d3de42d297..e08e28f4f0 100644 --- a/arch/arm/include/asm/arch-rockchip/sdram.h +++ b/arch/arm/include/asm/arch-rockchip/sdram.h @@ -24,6 +24,12 @@ struct rk3288_sdram_channel { u8 row_3_4; u8 cs0_row; u8 cs1_row; + /* + * For of-platdata, which would otherwise convert this into two + * byte-swapped integers. With a size of 9 bytes, this struct will + * appear in of-platdata as a byte array. + */ + u8 dummy; }; struct rk3288_sdram_pctl_timing { @@ -81,12 +87,4 @@ struct rk3288_base_params { u32 odt; }; -struct rk3288_sdram_params { - struct rk3288_sdram_channel ch[2]; - struct rk3288_sdram_pctl_timing pctl_timing; - struct rk3288_sdram_phy_timing phy_timing; - struct rk3288_base_params base; - int num_channels; -}; - #endif diff --git a/arch/arm/include/asm/arch-stm32f7/fmc.h b/arch/arm/include/asm/arch-stm32f7/fmc.h new file mode 100644 index 0000000000..7dd5077d0c --- /dev/null +++ b/arch/arm/include/asm/arch-stm32f7/fmc.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2013 + * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com + * + * (C) Copyright 2015 + * Kamil Lulko, <kamil.lulko@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _MACH_FMC_H_ +#define _MACH_FMC_H_ + +struct stm32_fmc_regs { + u32 sdcr1; /* Control register 1 */ + u32 sdcr2; /* Control register 2 */ + u32 sdtr1; /* Timing register 1 */ + u32 sdtr2; /* Timing register 2 */ + u32 sdcmr; /* Mode register */ + u32 sdrtr; /* Refresh timing register */ + u32 sdsr; /* Status register */ +}; + +/* + * FMC registers base + */ +#define STM32_SDRAM_FMC_BASE 0xA0000140 +#define STM32_SDRAM_FMC ((struct stm32_fmc_regs *)STM32_SDRAM_FMC_BASE) + +/* Control register SDCR */ +#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */ +#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */ +#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */ +#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */ +#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */ +#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */ +#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */ +#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */ +#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */ + +/* Timings register SDTR */ +#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */ +#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */ +#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */ +#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */ +#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */ +#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */ +#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */ + + +#define FMC_SDCMR_NRFS_SHIFT 5 + +#define FMC_SDCMR_MODE_NORMAL 0 +#define FMC_SDCMR_MODE_START_CLOCK 1 +#define FMC_SDCMR_MODE_PRECHARGE 2 +#define FMC_SDCMR_MODE_AUTOREFRESH 3 +#define FMC_SDCMR_MODE_WRITE_MODE 4 +#define FMC_SDCMR_MODE_SELFREFRESH 5 +#define FMC_SDCMR_MODE_POWERDOWN 6 + +#define FMC_SDCMR_BANK_1 (1 << 4) +#define FMC_SDCMR_BANK_2 (1 << 3) + +#define FMC_SDCMR_MODE_REGISTER_SHIFT 9 + +#define FMC_SDSR_BUSY (1 << 5) + +#define FMC_BUSY_WAIT() do { \ + __asm__ __volatile__ ("dsb" : : : "memory"); \ + while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \ + ; \ + } while (0) + + +#endif /* _MACH_FMC_H_ */ diff --git a/arch/arm/include/asm/arch-stm32f7/stm32.h b/arch/arm/include/asm/arch-stm32f7/stm32.h index 68bdab069d..de55ae5df1 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32.h @@ -64,6 +64,52 @@ enum clock { }; #define STM32_BUS_MASK 0xFFFF0000 +struct stm32_rcc_regs { + u32 cr; /* RCC clock control */ + u32 pllcfgr; /* RCC PLL configuration */ + u32 cfgr; /* RCC clock configuration */ + u32 cir; /* RCC clock interrupt */ + u32 ahb1rstr; /* RCC AHB1 peripheral reset */ + u32 ahb2rstr; /* RCC AHB2 peripheral reset */ + u32 ahb3rstr; /* RCC AHB3 peripheral reset */ + u32 rsv0; + u32 apb1rstr; /* RCC APB1 peripheral reset */ + u32 apb2rstr; /* RCC APB2 peripheral reset */ + u32 rsv1[2]; + u32 ahb1enr; /* RCC AHB1 peripheral clock enable */ + u32 ahb2enr; /* RCC AHB2 peripheral clock enable */ + u32 ahb3enr; /* RCC AHB3 peripheral clock enable */ + u32 rsv2; + u32 apb1enr; /* RCC APB1 peripheral clock enable */ + u32 apb2enr; /* RCC APB2 peripheral clock enable */ + u32 rsv3[2]; + u32 ahb1lpenr; /* RCC AHB1 periph clk enable in low pwr mode */ + u32 ahb2lpenr; /* RCC AHB2 periph clk enable in low pwr mode */ + u32 ahb3lpenr; /* RCC AHB3 periph clk enable in low pwr mode */ + u32 rsv4; + u32 apb1lpenr; /* RCC APB1 periph clk enable in low pwr mode */ + u32 apb2lpenr; /* RCC APB2 periph clk enable in low pwr mode */ + u32 rsv5[2]; + u32 bdcr; /* RCC Backup domain control */ + u32 csr; /* RCC clock control & status */ + u32 rsv6[2]; + u32 sscgr; /* RCC spread spectrum clock generation */ + u32 plli2scfgr; /* RCC PLLI2S configuration */ + u32 pllsaicfgr; + u32 dckcfgr; +}; +#define STM32_RCC ((struct stm32_rcc_regs *)RCC_BASE) + +struct stm32_pwr_regs { + u32 cr1; /* power control register 1 */ + u32 csr1; /* power control/status register 2 */ + u32 cr2; /* power control register 2 */ + u32 csr2; /* power control/status register 2 */ +}; +#define STM32_PWR ((struct stm32_pwr_regs *)PWR_BASE) + int configure_clocks(void); +unsigned long clock_get(enum clock clck); +void stm32_flash_latency_cfg(int latency); #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h index 38adc4e0e2..0bd4695727 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h @@ -17,11 +17,13 @@ enum periph_id { UART1_GPIOA_9_10 = 0, UART2_GPIOD_5_6, + UART6_GPIOC_6_7, }; enum periph_clock { USART1_CLOCK_CFG = 0, USART2_CLOCK_CFG, + USART6_CLOCK_CFG, GPIO_A_CLOCK_CFG, GPIO_B_CLOCK_CFG, GPIO_C_CLOCK_CFG, diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index c2e72f5a86..d4dff1e346 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -40,7 +40,8 @@ struct sunxi_ccm_reg { u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */ u32 apb1_gate; /* 0x68 apb1 module clock gating */ u32 apb2_gate; /* 0x6c apb2 module clock gating */ - u32 reserved9[4]; + u32 bus_gate4; /* 0x70 gate 4 module clock gating */ + u8 res3[0xc]; u32 nand0_clk_cfg; /* 0x80 nand0 clock control */ u32 nand1_clk_cfg; /* 0x84 nand1 clock control */ u32 sd0_clk_cfg; /* 0x88 sd0 clock control */ @@ -387,6 +388,7 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_LCD0 4 /* ahb_reset2 offsets */ +#define AHB_RESET_OFFSET_EPHY 2 #define AHB_RESET_OFFSET_LVDS 0 /* apb2 reset */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index c5e9d88bab..cd009d7ccc 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -87,7 +87,8 @@ #define SUNXI_KEYPAD_BASE 0x01c23000 #define SUNXI_TZPC_BASE 0x01c23400 -#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) +#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) || \ +defined(CONFIG_MACH_SUN50I) /* SID address space starts at 0x01c1400, but e-fuse is at offset 0x200 */ #define SUNXI_SID_BASE 0x01c14200 #else diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 1ace548022..bff7d1453f 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -141,6 +141,7 @@ enum sunxi_gpio_number { /* GPIO pin function config */ #define SUNXI_GPIO_INPUT 0 #define SUNXI_GPIO_OUTPUT 1 +#define SUNXI_GPIO_DISABLE 7 #define SUNXI_GPA_EMAC 2 #define SUN6I_GPA_GMAC 2 @@ -162,8 +163,10 @@ enum sunxi_gpio_number { #define SUN50I_GPB_UART0 4 #define SUNXI_GPC_NAND 2 +#define SUNXI_GPC_SPI0 3 #define SUNXI_GPC_SDC2 3 #define SUN6I_GPC_SDC3 4 +#define SUN50I_GPC_SPI0 4 #define SUN8I_GPD_SDC1 3 #define SUNXI_GPD_LCD0 2 diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index 3da360b177..cb52e64873 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -127,5 +127,4 @@ struct sunxi_mmc { #define SUNXI_MMC_COMMON_RESET (1 << 18) struct mmc *sunxi_mmc_init(int sdc_no); -int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc); #endif /* _SUNXI_MMC_H */ diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h index ec73379735..5d7ab559ef 100644 --- a/arch/arm/include/asm/arch-sunxi/spl.h +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -51,7 +51,14 @@ struct boot_file_head { uint8_t spl_signature[4]; }; uint32_t fel_script_address; - uint32_t reserved1[3]; + /* + * If the fel_uEnv_length member below is set to a non-zero value, + * it specifies the size (byte count) of data at fel_script_address. + * At the same time this indicates that the data is in uEnv.txt + * compatible format, ready to be imported via "env import -t". + */ + uint32_t fel_uEnv_length; + uint32_t reserved1[2]; uint32_t boot_media; /* written here by the boot ROM */ uint32_t reserved2[5]; /* padding, align to 64 bytes */ }; diff --git a/arch/arm/include/asm/arch-tegra/board.h b/arch/arm/include/asm/arch-tegra/board.h index 783bb3c0fa..a3db7ed604 100644 --- a/arch/arm/include/asm/arch-tegra/board.h +++ b/arch/arm/include/asm/arch-tegra/board.h @@ -20,7 +20,7 @@ void gpio_early_init(void); /* overrideable GPIO config */ /* * Hooks to allow boards to set up the pinmux for a specific function. * Has to be implemented in the board files as we don't yet support pinmux - * setup from FTD. If a board file does not implement one of those functions + * setup from FDT. If a board file does not implement one of those functions * an empty stub function will be called. */ diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h index e56031d1af..7daf8bc163 100644 --- a/arch/arm/include/asm/arch-tegra/clock.h +++ b/arch/arm/include/asm/arch-tegra/clock.h @@ -324,7 +324,7 @@ enum periph_id clk_id_to_periph_id(int clk_id); * @param p post divider(DIVP) * @param cpcon base PLL charge pump(CPCON) * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot - * be overriden), 1 if PLL is already correct + * be overridden), 1 if PLL is already correct */ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon); diff --git a/arch/arm/include/asm/arch-tegra124/display.h b/arch/arm/include/asm/arch-tegra124/display.h index ca6644af34..c522faa936 100644 --- a/arch/arm/include/asm/arch-tegra124/display.h +++ b/arch/arm/include/asm/arch-tegra124/display.h @@ -11,7 +11,7 @@ /** * Register a new display based on device tree configuration. * - * The frame buffer can be positioned by U-Boot or overriden by the fdt. + * The frame buffer can be positioned by U-Boot or overridden by the fdt. * You should pass in the U-Boot address here, and check the contents of * struct fdt_disp_config to see what was actually chosen. * diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h index 423fc70111..a20702e612 100644 --- a/arch/arm/include/asm/armv7.h +++ b/arch/arm/include/asm/armv7.h @@ -126,6 +126,8 @@ void _smp_pen(void); extern char __secure_start[]; extern char __secure_end[]; +extern char __secure_stack_start[]; +extern char __secure_stack_end[]; #endif /* CONFIG_ARMV7_NONSEC */ diff --git a/arch/arm/include/asm/armv7m.h b/arch/arm/include/asm/armv7m.h index 200444dda1..54d8a2bdff 100644 --- a/arch/arm/include/asm/armv7m.h +++ b/arch/arm/include/asm/armv7m.h @@ -51,10 +51,21 @@ struct v7m_mpu { #define V7M_MPU_CTRL_ENABLE (1 << 0) #define V7M_MPU_CTRL_HFNMIENA (1 << 1) +#define V7M_MPU_CTRL_ENABLE (1 << 0) +#define V7M_MPU_CTRL_DISABLE (0 << 0) +#define V7M_MPU_CTRL_HFNMIENA (1 << 1) + #define V7M_MPU_RASR_EN (1 << 0) #define V7M_MPU_RASR_SIZE_BITS 1 #define V7M_MPU_RASR_SIZE_4GB (31 << V7M_MPU_RASR_SIZE_BITS) +#define V7M_MPU_RASR_SIZE_8MB (24 << V7M_MPU_RASR_SIZE_BITS) +#define V7M_MPU_RASR_TEX_SHIFT 19 +#define V7M_MPU_RASR_S_SHIFT 18 +#define V7M_MPU_RASR_C_SHIFT 17 +#define V7M_MPU_RASR_B_SHIFT 16 #define V7M_MPU_RASR_AP_RW_RW (3 << 24) +#define V7M_MPU_RASR_XN_ENABLE (0 << 28) +#define V7M_MPU_RASR_XN_DISABLE (1 << 28) #endif /* !defined(__ASSEMBLY__) */ #endif /* ARMV7M_H */ diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 1f63127bdc..16e65c36a9 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -29,6 +29,8 @@ static inline void invalidate_l2_cache(void) } #endif +int check_cache_range(unsigned long start, unsigned long stop); + void l2_cache_enable(void); void l2_cache_disable(void); void set_section_dcache(int section, enum dcache_option option); diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 9d185a6122..6121f1ddca 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -292,40 +292,6 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen) #define readsb(a, d, s) __raw_readsb((unsigned long)a, d, s) /* - * ioremap and friends. - * - * ioremap takes a PCI memory address, as specified in - * linux/Documentation/IO-mapping.txt. If you want a - * physical address, use __ioremap instead. - */ -extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags); -extern void __iounmap(void *addr); - -/* - * Generic ioremap support. - * - * Define: - * iomem_valid_addr(off,size) - * iomem_to_phys(off) - */ -#ifdef iomem_valid_addr -#define __arch_ioremap(off,sz,nocache) \ - ({ \ - unsigned long _off = (off), _size = (sz); \ - void *_ret = (void *)0; \ - if (iomem_valid_addr(_off, _size)) \ - _ret = __ioremap(iomem_to_phys(_off),_size,nocache); \ - _ret; \ - }) - -#define __arch_iounmap __iounmap -#endif - -#define ioremap(off,sz) __arch_ioremap((off),(sz),0) -#define ioremap_nocache(off,sz) __arch_ioremap((off),(sz),1) -#define iounmap(_addr) __arch_iounmap(_addr) - -/* * DMA-consistent mapping functions. These allocate/free a region of * uncached, unwrite-buffered mapped memory space for use with DMA * devices. This is the "generic" version. The PCI specific version diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 07f384867e..605c549f0a 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -627,6 +627,12 @@ void recalibrate_iodelay(void); void omap_smc1(u32 service, u32 val); +/* + * Low-level helper function used when performing secure ROM calls on high- + * security (HS) device variants by doing a specially-formed smc entry. + */ +u32 omap_smc_sec(u32 service, u32 proc_id, u32 flag, u32 *params); + void enable_edma3_clocks(void); void disable_edma3_clocks(void); diff --git a/arch/arm/include/asm/omap_sec_common.h b/arch/arm/include/asm/omap_sec_common.h new file mode 100644 index 0000000000..842f2af8d1 --- /dev/null +++ b/arch/arm/include/asm/omap_sec_common.h @@ -0,0 +1,30 @@ +/* + * (C) Copyright 2016 + * Texas Instruments, <www.ti.com> + * + * Andreas Dannenberg <dannenberg@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _OMAP_SEC_COMMON_H_ +#define _OMAP_SEC_COMMON_H_ + +#include <common.h> + +/* + * Invoke secure ROM API on high-security (HS) device variants. It formats + * the variable argument list into the format expected by the ROM code before + * triggering the actual low-level smc entry. + */ +u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...); + +/* + * Invoke a secure ROM API on high-secure (HS) device variants that can be used + * to verify a secure blob by authenticating and optionally decrypting it. The + * exact operation performed depends on how the certificate that was embedded + * into the blob during the signing/encryption step when the secure blob was + * first created. + */ +int secure_boot_verify_image(void **p_image, size_t *p_size); + +#endif /* _OMAP_SEC_COMMON_H_ */ diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index f92633b13f..e76ecb27a7 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -47,12 +47,19 @@ #define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8) #define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9) +/* 1KB stack per core */ +#define ARM_PSCI_STACK_SHIFT 10 +#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT) + #ifndef __ASSEMBLY__ #include <asm/types.h> +/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */ +u32 psci_get_target_pc(int cpu); +void psci_save_target_pc(int cpu, u32 pc); + void psci_cpu_entry(void); u32 psci_get_cpu_id(void); -u32 psci_get_cpu_stack_top(int cpu); void psci_cpu_off_common(void); int psci_update_dt(void *fdt); diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index effdb1858d..5a403bc0f1 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -3,6 +3,9 @@ #include <config.h> +#define __secure __attribute__ ((section ("._secure.text"))) +#define __secure_data __attribute__ ((section ("._secure.data"))) + #ifdef CONFIG_ARMV7_SECURE_BASE /* * Warning, horror ahead. diff --git a/arch/arm/include/asm/spin_table.h b/arch/arm/include/asm/spin_table.h new file mode 100644 index 0000000000..8b57539f8d --- /dev/null +++ b/arch/arm/include/asm/spin_table.h @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_SPIN_TABLE_H__ +#define __ASM_SPIN_TABLE_H__ + +extern u64 spin_table_cpu_release_addr; +extern char spin_table_reserve_begin; +extern char spin_table_reserve_end; + +int spin_table_update_dt(void *fdt); + +#endif /* __ASM_SPIN_TABLE_H__ */ diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h index d108915ff5..9af7353f08 100644 --- a/arch/arm/include/asm/types.h +++ b/arch/arm/include/asm/types.h @@ -71,5 +71,4 @@ typedef u32 dma_addr_t; #endif /* __KERNEL__ */ -typedef unsigned long resource_size_t; #endif diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c index fe5b488339..4481f9e2fa 100644 --- a/arch/arm/lib/bootm-fdt.c +++ b/arch/arm/lib/bootm-fdt.c @@ -21,6 +21,7 @@ #include <asm/armv7.h> #endif #include <asm/psci.h> +#include <asm/spin_table.h> DECLARE_GLOBAL_DATA_PTR; @@ -45,6 +46,12 @@ int arch_fixup_fdt(void *blob) if (ret) return ret; +#ifdef CONFIG_ARMV8_SPIN_TABLE + ret = spin_table_update_dt(blob); + if (ret) + return ret; +#endif + #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV8_PSCI) ret = psci_update_dt(blob); if (ret) diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c index 3bd87105c5..d330b09434 100644 --- a/arch/arm/lib/cache.c +++ b/arch/arm/lib/cache.c @@ -10,6 +10,10 @@ #include <common.h> #include <malloc.h> +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE 32 +#endif + /* * Flush range from all levels of d-cache/unified-cache. * Affects the range [start, start + size - 1]. @@ -46,6 +50,24 @@ __weak void flush_dcache_range(unsigned long start, unsigned long stop) /* An empty stub, real implementation should be in platform code */ } +int check_cache_range(unsigned long start, unsigned long stop) +{ + int ok = 1; + + if (start & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1)) + ok = 0; + + if (!ok) { + warn_non_spl("CACHE: Misaligned operation at range [%08lx, %08lx]\n", + start, stop); + } + + return ok; +} + #ifdef CONFIG_SYS_NONCACHED_MEMORY /* * Reserve one MMU section worth of address space below the malloc() area that diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c index 6a94522418..952e8ae49b 100644 --- a/arch/arm/lib/sections.c +++ b/arch/arm/lib/sections.c @@ -27,6 +27,8 @@ char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); char __secure_start[0] __attribute__((section(".__secure_start"))); char __secure_end[0] __attribute__((section(".__secure_end"))); +char __secure_stack_start[0] __attribute__((section(".__secure_stack_start"))); +char __secure_stack_end[0] __attribute__((section(".__secure_stack_end"))); char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start"))); char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); char __efi_runtime_rel_start[0] __attribute__((section(".__efi_runtime_rel_start"))); diff --git a/arch/arm/mach-exynos/include/mach/dwmmc.h b/arch/arm/mach-exynos/include/mach/dwmmc.h index bd997ad47e..ab8361f4a8 100644 --- a/arch/arm/mach-exynos/include/mach/dwmmc.h +++ b/arch/arm/mach-exynos/include/mach/dwmmc.h @@ -28,4 +28,3 @@ #define DWMCI_DIVRATIO_MASK 0x7 int exynos_dwmmc_init(const void *blob); -int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel); diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index 15f1266a7b..123f58b27f 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -29,6 +29,7 @@ DECLARE_GLOBAL_DATA_PTR; u32 spl_boot_device(void) { +#if !CONFIG_IS_ENABLED(OF_PLATDATA) const void *blob = gd->fdt_blob; struct udevice *dev; const char *bootdev; @@ -63,6 +64,7 @@ u32 spl_boot_device(void) } fallback: +#endif return BOOT_DEVICE_MMC1; } @@ -114,7 +116,6 @@ static void configure_l2ctlr(void) #ifdef CONFIG_SPL_MMC_SUPPORT static int configure_emmc(struct udevice *pinctrl) { -#if !defined(CONFIG_TARGET_ROCK2) && !defined(CONFIG_TARGET_FIREFLY_RK3288) struct gpio_desc desc; int ret; @@ -144,7 +145,6 @@ static int configure_emmc(struct udevice *pinctrl) debug("gpio value ret=%d\n", ret); return ret; } -#endif return 0; } @@ -247,15 +247,18 @@ void spl_board_init(void) goto err; } #ifdef CONFIG_SPL_MMC_SUPPORT - ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD); - if (ret) { - debug("%s: Failed to set up SD card\n", __func__); - goto err; - } - ret = configure_emmc(pinctrl); - if (ret) { - debug("%s: Failed to set up eMMC\n", __func__); - goto err; + if (!IS_ENABLED(CONFIG_TARGET_ROCK2) && + !IS_ENABLED(CONFIG_TARGET_FIREFLY_RK3288)) { + ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD); + if (ret) { + debug("%s: Failed to set up SD card\n", __func__); + goto err; + } + ret = configure_emmc(pinctrl); + if (ret) { + debug("%s: Failed to set up eMMC\n", __func__); + goto err; + } } #endif diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c index 55ac73e9d2..b36b6afcd9 100644 --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c @@ -10,6 +10,7 @@ #include <common.h> #include <clk.h> #include <dm.h> +#include <dt-structs.h> #include <errno.h> #include <ram.h> #include <regmap.h> @@ -41,6 +42,19 @@ struct dram_info { struct rk3288_grf *grf; struct rk3288_sgrf *sgrf; struct rk3288_pmu *pmu; + bool is_veyron; +}; + +struct rk3288_sdram_params { +#if CONFIG_IS_ENABLED(OF_PLATDATA) + struct dtd_rockchip_rk3288_dmc of_plat; +#endif + struct rk3288_sdram_channel ch[2]; + struct rk3288_sdram_pctl_timing pctl_timing; + struct rk3288_sdram_phy_timing phy_timing; + struct rk3288_base_params base; + int num_channels; + struct regmap *map; }; #ifdef CONFIG_SPL_BUILD @@ -703,7 +717,7 @@ static int sdram_init(struct dram_info *dram, return 0; } -#endif +#endif /* CONFIG_SPL_BUILD */ size_t sdram_size_mb(struct rk3288_pmu *pmu) { @@ -779,18 +793,36 @@ static int veyron_init(struct dram_info *priv) static int setup_sdram(struct udevice *dev) { struct dram_info *priv = dev_get_priv(dev); - struct rk3288_sdram_params params; + struct rk3288_sdram_params *params = dev_get_platdata(dev); + +# ifdef CONFIG_ROCKCHIP_FAST_SPL + if (priv->is_veyron) { + int ret; + + ret = veyron_init(priv); + if (ret) + return ret; + } +# endif + + return sdram_init(priv, params); +} + +static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev) +{ +#if !CONFIG_IS_ENABLED(OF_PLATDATA) + struct rk3288_sdram_params *params = dev_get_platdata(dev); const void *blob = gd->fdt_blob; int node = dev->of_offset; int i, ret; - params.num_channels = fdtdec_get_int(blob, node, - "rockchip,num-channels", 1); - for (i = 0; i < params.num_channels; i++) { + params->num_channels = fdtdec_get_int(blob, node, + "rockchip,num-channels", 1); + for (i = 0; i < params->num_channels; i++) { ret = fdtdec_get_byte_array(blob, node, "rockchip,sdram-channel", - (u8 *)¶ms.ch[i], - sizeof(params.ch[i])); + (u8 *)¶ms->ch[i], + sizeof(params->ch[i])); if (ret) { debug("%s: Cannot read rockchip,sdram-channel\n", __func__); @@ -798,46 +830,82 @@ static int setup_sdram(struct udevice *dev) } } ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing", - (u32 *)¶ms.pctl_timing, - sizeof(params.pctl_timing) / sizeof(u32)); + (u32 *)¶ms->pctl_timing, + sizeof(params->pctl_timing) / sizeof(u32)); if (ret) { debug("%s: Cannot read rockchip,pctl-timing\n", __func__); return -EINVAL; } ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing", - (u32 *)¶ms.phy_timing, - sizeof(params.phy_timing) / sizeof(u32)); + (u32 *)¶ms->phy_timing, + sizeof(params->phy_timing) / sizeof(u32)); if (ret) { debug("%s: Cannot read rockchip,phy-timing\n", __func__); return -EINVAL; } ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params", - (u32 *)¶ms.base, - sizeof(params.base) / sizeof(u32)); + (u32 *)¶ms->base, + sizeof(params->base) / sizeof(u32)); if (ret) { debug("%s: Cannot read rockchip,sdram-params\n", __func__); return -EINVAL; } +#ifdef CONFIG_ROCKCHIP_FAST_SPL + struct dram_info *priv = dev_get_priv(dev); -# ifdef CONFIG_ROCKCHIP_FAST_SPL - if (!fdt_node_check_compatible(blob, 0, "google,veyron")) { - ret = veyron_init(priv); - if (ret) - return ret; + priv->is_veyron = !fdt_node_check_compatible(blob, 0, "google,veyron"); +#endif + ret = regmap_init_mem(dev, ¶ms->map); + if (ret) + return ret; +#endif + + return 0; +} +#endif /* CONFIG_SPL_BUILD */ + +#if CONFIG_IS_ENABLED(OF_PLATDATA) +static int conv_of_platdata(struct udevice *dev) +{ + struct rk3288_sdram_params *plat = dev_get_platdata(dev); + struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat; + int i, ret; + + for (i = 0; i < 2; i++) { + memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel, + sizeof(plat->ch[i])); } -# endif + memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing, + sizeof(plat->pctl_timing)); + memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing, + sizeof(plat->phy_timing)); + memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base)); + plat->num_channels = of_plat->rockchip_num_channels; + ret = regmap_init_mem_platdata(dev, of_plat->reg, + ARRAY_SIZE(of_plat->reg) / 2, + &plat->map); + if (ret) + return ret; - return sdram_init(priv, ¶ms); + return 0; } #endif static int rk3288_dmc_probe(struct udevice *dev) { +#ifdef CONFIG_SPL_BUILD + struct rk3288_sdram_params *plat = dev_get_platdata(dev); +#endif struct dram_info *priv = dev_get_priv(dev); struct regmap *map; int ret; struct udevice *dev_clk; +#if CONFIG_IS_ENABLED(OF_PLATDATA) + ret = conv_of_platdata(dev); + if (ret) + return ret; +#endif map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC); if (IS_ERR(map)) return PTR_ERR(map); @@ -849,14 +917,12 @@ static int rk3288_dmc_probe(struct udevice *dev) priv->sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_SGRF); priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); - ret = regmap_init_mem(dev, &map); - if (ret) - return ret; - priv->chan[0].pctl = regmap_get_range(map, 0); - priv->chan[0].publ = regmap_get_range(map, 1); - priv->chan[1].pctl = regmap_get_range(map, 2); - priv->chan[1].publ = regmap_get_range(map, 3); - +#ifdef CONFIG_SPL_BUILD + priv->chan[0].pctl = regmap_get_range(plat->map, 0); + priv->chan[0].publ = regmap_get_range(plat->map, 1); + priv->chan[1].pctl = regmap_get_range(plat->map, 2); + priv->chan[1].publ = regmap_get_range(plat->map, 3); +#endif ret = uclass_get_device(UCLASS_CLK, 0, &dev_clk); if (ret) return ret; @@ -898,10 +964,16 @@ static const struct udevice_id rk3288_dmc_ids[] = { }; U_BOOT_DRIVER(dmc_rk3288) = { - .name = "rk3288_dmc", + .name = "rockchip_rk3288_dmc", .id = UCLASS_RAM, .of_match = rk3288_dmc_ids, .ops = &rk3288_dmc_ops, +#ifdef CONFIG_SPL_BUILD + .ofdata_to_platdata = rk3288_dmc_ofdata_to_platdata, +#endif .probe = rk3288_dmc_probe, .priv_auto_alloc_size = sizeof(struct dram_info), +#ifdef CONFIG_SPL_BUILD + .platdata_auto_alloc_size = sizeof(struct rk3288_sdram_params), +#endif }; diff --git a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c index c9f7c4e32f..be4b2b00c3 100644 --- a/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c @@ -23,3 +23,41 @@ U_BOOT_DRIVER(syscon_rk3288) = { .id = UCLASS_SYSCON, .of_match = rk3288_syscon_ids, }; + +#if CONFIG_IS_ENABLED(OF_PLATDATA) +static int rk3288_syscon_bind_of_platdata(struct udevice *dev) +{ + dev->driver_data = dev->driver->of_match->data; + debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data); + + return 0; +} + +U_BOOT_DRIVER(rockchip_rk3288_noc) = { + .name = "rockchip_rk3288_noc", + .id = UCLASS_SYSCON, + .of_match = rk3288_syscon_ids, + .bind = rk3288_syscon_bind_of_platdata, +}; + +U_BOOT_DRIVER(rockchip_rk3288_grf) = { + .name = "rockchip_rk3288_grf", + .id = UCLASS_SYSCON, + .of_match = rk3288_syscon_ids + 1, + .bind = rk3288_syscon_bind_of_platdata, +}; + +U_BOOT_DRIVER(rockchip_rk3288_sgrf) = { + .name = "rockchip_rk3288_sgrf", + .id = UCLASS_SYSCON, + .of_match = rk3288_syscon_ids + 2, + .bind = rk3288_syscon_bind_of_platdata, +}; + +U_BOOT_DRIVER(rockchip_rk3288_pmu) = { + .name = "rockchip_rk3288_pmu", + .id = UCLASS_SYSCON, + .of_match = rk3288_syscon_ids + 3, + .bind = rk3288_syscon_bind_of_platdata, +}; +#endif diff --git a/arch/arm/mach-stm32/stm32f7/Makefile b/arch/arm/mach-stm32/stm32f7/Makefile index 40f1ad35b7..643d4d919c 100644 --- a/arch/arm/mach-stm32/stm32f7/Makefile +++ b/arch/arm/mach-stm32/stm32f7/Makefile @@ -5,4 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += timer.o clock.o +obj-y += timer.o clock.o soc.o diff --git a/arch/arm/mach-stm32/stm32f7/clock.c b/arch/arm/mach-stm32/stm32f7/clock.c index 17a715bac9..ac47850551 100644 --- a/arch/arm/mach-stm32/stm32f7/clock.c +++ b/arch/arm/mach-stm32/stm32f7/clock.c @@ -11,12 +11,243 @@ #include <asm/arch/stm32.h> #include <asm/arch/stm32_periph.h> +#define RCC_CR_HSION (1 << 0) +#define RCC_CR_HSEON (1 << 16) +#define RCC_CR_HSERDY (1 << 17) +#define RCC_CR_HSEBYP (1 << 18) +#define RCC_CR_CSSON (1 << 19) +#define RCC_CR_PLLON (1 << 24) +#define RCC_CR_PLLRDY (1 << 25) + +#define RCC_PLLCFGR_PLLM_MASK 0x3F +#define RCC_PLLCFGR_PLLN_MASK 0x7FC0 +#define RCC_PLLCFGR_PLLP_MASK 0x30000 +#define RCC_PLLCFGR_PLLQ_MASK 0xF000000 +#define RCC_PLLCFGR_PLLSRC (1 << 22) +#define RCC_PLLCFGR_PLLM_SHIFT 0 +#define RCC_PLLCFGR_PLLN_SHIFT 6 +#define RCC_PLLCFGR_PLLP_SHIFT 16 +#define RCC_PLLCFGR_PLLQ_SHIFT 24 + +#define RCC_CFGR_AHB_PSC_MASK 0xF0 +#define RCC_CFGR_APB1_PSC_MASK 0x1C00 +#define RCC_CFGR_APB2_PSC_MASK 0xE000 +#define RCC_CFGR_SW0 (1 << 0) +#define RCC_CFGR_SW1 (1 << 1) +#define RCC_CFGR_SW_MASK 0x3 +#define RCC_CFGR_SW_HSI 0 +#define RCC_CFGR_SW_HSE RCC_CFGR_SW0 +#define RCC_CFGR_SW_PLL RCC_CFGR_SW1 +#define RCC_CFGR_SWS0 (1 << 2) +#define RCC_CFGR_SWS1 (1 << 3) +#define RCC_CFGR_SWS_MASK 0xC +#define RCC_CFGR_SWS_HSI 0 +#define RCC_CFGR_SWS_HSE RCC_CFGR_SWS0 +#define RCC_CFGR_SWS_PLL RCC_CFGR_SWS1 +#define RCC_CFGR_HPRE_SHIFT 4 +#define RCC_CFGR_PPRE1_SHIFT 10 +#define RCC_CFGR_PPRE2_SHIFT 13 + +#define RCC_APB1ENR_PWREN (1 << 28) + +/* + * RCC USART specific definitions + */ +#define RCC_ENR_USART1EN (1 << 4) +#define RCC_ENR_USART2EN (1 << 17) +#define RCC_ENR_USART3EN (1 << 18) +#define RCC_ENR_USART6EN (1 << 5) + +/* + * Offsets of some PWR registers + */ +#define PWR_CR1_ODEN (1 << 16) +#define PWR_CR1_ODSWEN (1 << 17) +#define PWR_CSR1_ODRDY (1 << 16) +#define PWR_CSR1_ODSWRDY (1 << 17) + + +/* + * RCC GPIO specific definitions + */ +#define RCC_ENR_GPIO_A_EN (1 << 0) +#define RCC_ENR_GPIO_B_EN (1 << 1) +#define RCC_ENR_GPIO_C_EN (1 << 2) +#define RCC_ENR_GPIO_D_EN (1 << 3) +#define RCC_ENR_GPIO_E_EN (1 << 4) +#define RCC_ENR_GPIO_F_EN (1 << 5) +#define RCC_ENR_GPIO_G_EN (1 << 6) +#define RCC_ENR_GPIO_H_EN (1 << 7) +#define RCC_ENR_GPIO_I_EN (1 << 8) +#define RCC_ENR_GPIO_J_EN (1 << 9) +#define RCC_ENR_GPIO_K_EN (1 << 10) + +struct pll_psc { + u8 pll_m; + u16 pll_n; + u8 pll_p; + u8 pll_q; + u8 ahb_psc; + u8 apb1_psc; + u8 apb2_psc; +}; + +#define AHB_PSC_1 0 +#define AHB_PSC_2 0x8 +#define AHB_PSC_4 0x9 +#define AHB_PSC_8 0xA +#define AHB_PSC_16 0xB +#define AHB_PSC_64 0xC +#define AHB_PSC_128 0xD +#define AHB_PSC_256 0xE +#define AHB_PSC_512 0xF + +#define APB_PSC_1 0 +#define APB_PSC_2 0x4 +#define APB_PSC_4 0x5 +#define APB_PSC_8 0x6 +#define APB_PSC_16 0x7 + +#if !defined(CONFIG_STM32_HSE_HZ) +#error "CONFIG_STM32_HSE_HZ not defined!" +#else +#if (CONFIG_STM32_HSE_HZ == 25000000) +#if (CONFIG_SYS_CLK_FREQ == 200000000) +/* 200 MHz */ +struct pll_psc sys_pll_psc = { + .pll_m = 25, + .pll_n = 400, + .pll_p = 2, + .pll_q = 8, + .ahb_psc = AHB_PSC_1, + .apb1_psc = APB_PSC_4, + .apb2_psc = APB_PSC_2 +}; +#endif +#else +#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists" +#endif +#endif + +int configure_clocks(void) +{ + /* Reset RCC configuration */ + setbits_le32(&STM32_RCC->cr, RCC_CR_HSION); + writel(0, &STM32_RCC->cfgr); /* Reset CFGR */ + clrbits_le32(&STM32_RCC->cr, (RCC_CR_HSEON | RCC_CR_CSSON + | RCC_CR_PLLON)); + writel(0x24003010, &STM32_RCC->pllcfgr); /* Reset value from RM */ + clrbits_le32(&STM32_RCC->cr, RCC_CR_HSEBYP); + writel(0, &STM32_RCC->cir); /* Disable all interrupts */ + + /* Configure for HSE+PLL operation */ + setbits_le32(&STM32_RCC->cr, RCC_CR_HSEON); + while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY)) + ; + + setbits_le32(&STM32_RCC->cfgr, (( + sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT) + | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT) + | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT))); + + /* Configure the main PLL */ + uint32_t pllcfgr = 0; + pllcfgr = RCC_PLLCFGR_PLLSRC; /* pll source HSE */ + pllcfgr |= sys_pll_psc.pll_m << RCC_PLLCFGR_PLLM_SHIFT; + pllcfgr |= sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT; + pllcfgr |= ((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT; + pllcfgr |= sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT; + writel(pllcfgr, &STM32_RCC->pllcfgr); + + /* Enable the main PLL */ + setbits_le32(&STM32_RCC->cr, RCC_CR_PLLON); + while (!(readl(&STM32_RCC->cr) & RCC_CR_PLLRDY)) + ; + + /* Enable high performance mode, System frequency up to 200 MHz */ + setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN); + setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODEN); + /* Infinite wait! */ + while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODRDY)) + ; + /* Enable the Over-drive switch */ + setbits_le32(&STM32_PWR->cr1, PWR_CR1_ODSWEN); + /* Infinite wait! */ + while (!(readl(&STM32_PWR->csr1) & PWR_CSR1_ODSWRDY)) + ; + + stm32_flash_latency_cfg(5); + clrbits_le32(&STM32_RCC->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1)); + setbits_le32(&STM32_RCC->cfgr, RCC_CFGR_SW_PLL); + + while ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) != + RCC_CFGR_SWS_PLL) + ; + + return 0; +} + +unsigned long clock_get(enum clock clck) +{ + u32 sysclk = 0; + u32 shift = 0; + /* Prescaler table lookups for clock computation */ + u8 ahb_psc_table[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9 + }; + u8 apb_psc_table[8] = { + 0, 0, 0, 0, 1, 2, 3, 4 + }; + + if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) == + RCC_CFGR_SWS_PLL) { + u16 pllm, plln, pllp; + pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); + plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK) + >> RCC_PLLCFGR_PLLN_SHIFT); + pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK) + >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1); + sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp; + } + + switch (clck) { + case CLOCK_CORE: + return sysclk; + break; + case CLOCK_AHB: + shift = ahb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK) + >> RCC_CFGR_HPRE_SHIFT)]; + return sysclk >>= shift; + break; + case CLOCK_APB1: + shift = apb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK) + >> RCC_CFGR_PPRE1_SHIFT)]; + return sysclk >>= shift; + break; + case CLOCK_APB2: + shift = apb_psc_table[( + (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK) + >> RCC_CFGR_PPRE2_SHIFT)]; + return sysclk >>= shift; + break; + default: + return 0; + break; + } +} + + void clock_setup(int peripheral) { switch (peripheral) { case USART1_CLOCK_CFG: setbits_le32(RCC_BASE + RCC_APB2ENR, RCC_ENR_USART1EN); break; + case USART6_CLOCK_CFG: + setbits_le32(RCC_BASE + RCC_APB2ENR, RCC_ENR_USART6EN); + break; case GPIO_A_CLOCK_CFG: setbits_le32(RCC_BASE + RCC_AHB1ENR, RCC_ENR_GPIO_A_EN); break; diff --git a/arch/arm/mach-stm32/stm32f7/soc.c b/arch/arm/mach-stm32/stm32f7/soc.c new file mode 100644 index 0000000000..8baee99a4f --- /dev/null +++ b/arch/arm/mach-stm32/stm32f7/soc.c @@ -0,0 +1,76 @@ +/* + * (C) Copyright 2015 + * Kamil Lulko, <kamil.lulko@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/armv7m.h> +#include <asm/arch/stm32.h> + +u32 get_cpu_rev(void) +{ + return 0; +} + +int arch_cpu_init(void) +{ + configure_clocks(); + + /* + * Configure the memory protection unit (MPU) + * 0x00000000 - 0xffffffff: Strong-order, Shareable + * 0xC0000000 - 0xC0800000: Normal, Outer and inner Non-cacheable + */ + + /* Disable MPU */ + writel(0, &V7M_MPU->ctrl); + + writel( + 0x00000000 /* address */ + | 1 << 4 /* VALID */ + | 0 << 0 /* REGION */ + , &V7M_MPU->rbar + ); + + /* Strong-order, Shareable */ + /* TEX=000, S=1, C=0, B=0*/ + writel( + (V7M_MPU_RASR_XN_ENABLE + | V7M_MPU_RASR_AP_RW_RW + | 0x01 << V7M_MPU_RASR_S_SHIFT + | 0x00 << V7M_MPU_RASR_TEX_SHIFT + | V7M_MPU_RASR_SIZE_4GB + | V7M_MPU_RASR_EN) + , &V7M_MPU->rasr + ); + + writel( + 0xC0000000 /* address */ + | 1 << 4 /* VALID */ + | 1 << 0 /* REGION */ + , &V7M_MPU->rbar + ); + + /* Normal, Outer and inner Non-cacheable */ + /* TEX=001, S=0, C=0, B=0*/ + writel( + (V7M_MPU_RASR_XN_ENABLE + | V7M_MPU_RASR_AP_RW_RW + | 0x01 << V7M_MPU_RASR_TEX_SHIFT + | V7M_MPU_RASR_SIZE_8MB + | V7M_MPU_RASR_EN) + , &V7M_MPU->rasr + ); + + /* Enable MPU */ + writel(V7M_MPU_CTRL_ENABLE | V7M_MPU_CTRL_HFNMIENA, &V7M_MPU->ctrl); + + return 0; +} + +void s_init(void) +{ +} diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 01bfc93cbb..6d9518d4c6 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -205,7 +205,8 @@ DECLARE_GLOBAL_DATA_PTR; */ u32 spl_boot_device(void) { - __maybe_unused struct mmc *mmc0, *mmc1; + int boot_source; + /* * When booting from the SD card or NAND memory, the "eGON.BT0" * signature is expected to be found in memory at the address 0x0004 @@ -225,27 +226,19 @@ u32 spl_boot_device(void) if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ return BOOT_DEVICE_BOARD; - /* The BROM will try to boot from mmc0 first, so try that first. */ -#ifdef CONFIG_MMC - mmc_initialize(gd->bd); - mmc0 = find_mmc_device(0); - if (sunxi_mmc_has_egon_boot_signature(mmc0)) + boot_source = readb(SPL_ADDR + 0x28); + switch (boot_source) { + case SUNXI_BOOTED_FROM_MMC0: return BOOT_DEVICE_MMC1; -#endif - - /* Fallback to booting NAND if enabled. */ - if (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT)) + case SUNXI_BOOTED_FROM_NAND: return BOOT_DEVICE_NAND; - -#ifdef CONFIG_MMC - if (CONFIG_MMC_SUNXI_SLOT_EXTRA == 2) { - mmc1 = find_mmc_device(1); - if (sunxi_mmc_has_egon_boot_signature(mmc1)) - return BOOT_DEVICE_MMC2; + case SUNXI_BOOTED_FROM_MMC2: + return BOOT_DEVICE_MMC2; + case SUNXI_BOOTED_FROM_SPI: + return BOOT_DEVICE_SPI; } -#endif - panic("Could not determine boot source\n"); + panic("Unknown boot source %d\n", boot_source); return -1; /* Never reached */ } diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index c50d56dc88..36eabc8f57 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -510,7 +510,7 @@ unsigned clock_get_rate(enum clock_id clkid) * @param p post divider(DIVP) * @param cpcon base PLL charge pump(CPCON) * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot - * be overriden), 1 if PLL is already correct + * be overridden), 1 if PLL is already correct */ int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon) { diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index b836da1c0e..645d08fa0b 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -61,9 +61,6 @@ ENTRY(psci_arch_init) ldrne r7, [r5] mcrne p15, 0, r7, c14, c0, 0 @ write CNTFRQ to CPU1..3 - bl psci_get_cpu_stack_top @ stack top => r0 - mov sp, r0 - bx r6 ENDPROC(psci_arch_init) @@ -88,12 +85,13 @@ _loop: wfi ENDPROC(psci_cpu_off) ENTRY(psci_cpu_on) - push {lr} + push {r4, r5, r6, lr} + mov r4, r1 mov r0, r1 - bl psci_get_cpu_stack_top @ get stack top of target CPU - str r2, [r0] @ store target PC at stack top - dsb + mov r1, r2 + bl psci_save_target_pc @ store target PC + mov r1, r4 ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry @@ -106,9 +104,7 @@ ENTRY(psci_cpu_on) str r5, [r6, r2] mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS - pop {pc} + pop {r4, r5, r6, pc} ENDPROC(psci_cpu_on) - .globl psci_text_end -psci_text_end: .popsection |