mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 22:20:45 +00:00
Merge git://git.denx.de/u-boot-rockchip
This commit is contained in:
commit
d9d76023ea
60 changed files with 676 additions and 892 deletions
|
@ -1130,6 +1130,7 @@ config ARCH_ROCKCHIP
|
|||
select DM_USB if USB
|
||||
select DM_PWM
|
||||
select DM_REGULATOR
|
||||
select ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
imply CMD_FASTBOOT
|
||||
imply FASTBOOT
|
||||
imply FAT_WRITE
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
.globl reset
|
||||
.globl save_boot_params_ret
|
||||
.type save_boot_params_ret,%function
|
||||
#ifdef CONFIG_ARMV7_LPAE
|
||||
.global switch_to_hypervisor_ret
|
||||
#endif
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
*/
|
||||
|
||||
/* BOOT0 header information */
|
||||
_start:
|
||||
ARM_VECTORS
|
||||
.word 0xbabeface
|
||||
.word _end - _start
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
*/
|
||||
|
||||
/* BOOT0 header information */
|
||||
_start:
|
||||
ARM_VECTORS
|
||||
.word 0xbabeface
|
||||
.word _end - _start
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* Copyright 2017 Theobroma Systems Design und Consulting GmbH
|
||||
*
|
||||
|
@ -7,26 +6,49 @@
|
|||
|
||||
/*
|
||||
* Execution starts on the instruction following this 4-byte header
|
||||
* (containing the magic 'RK33').
|
||||
* (containing the magic 'RK30', 'RK31', 'RK32' or 'RK33'). This
|
||||
* magic constant will be written into the final image by the rkimage
|
||||
* tool, but we need to reserve space for it here.
|
||||
*
|
||||
* To make life easier for everyone, we build the SPL binary with
|
||||
* space for this 4-byte header already included in the binary.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* We need to add 4 bytes of space for the 'RK33' at the
|
||||
* beginning of the executable. However, as we want to keep
|
||||
* this generic and make it applicable to builds that are like
|
||||
* the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no
|
||||
* TPL, but extra space needed in the SPL), we simply repeat
|
||||
* the 'b reset' with the expectation that the first one will
|
||||
* be overwritten, if this is the first stage contained in the
|
||||
* final image created with mkimage)...
|
||||
* TPL, but extra space needed in the SPL), we simply insert
|
||||
* a branch-to-next-instruction-word with the expectation that
|
||||
* the first one may be overwritten, if this is the first stage
|
||||
* contained in the final image created with mkimage)...
|
||||
*/
|
||||
b reset /* may be overwritten --- should be 'nop' or a 'b reset' */
|
||||
b 1f /* if overwritten, entry-address is at the next word */
|
||||
1:
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM)
|
||||
adr r3, entry_counter
|
||||
ldr r0, [r3]
|
||||
cmp r0, #1 /* check if entry_counter == 1 */
|
||||
beq reset /* regular bootup */
|
||||
add r0, #1
|
||||
str r0, [r3] /* increment the entry_counter in memory */
|
||||
mov r0, #0 /* return 0 to the BROM to signal 'OK' */
|
||||
bx lr /* return control to the BROM */
|
||||
entry_counter:
|
||||
.word 0
|
||||
#endif
|
||||
b reset
|
||||
#if !defined(CONFIG_ARM64)
|
||||
/*
|
||||
* For armv7, the addr '_start' will used as vector start address
|
||||
* and write to VBAR register, which needs to aligned to 0x20.
|
||||
*/
|
||||
.align(5), 0x0
|
||||
_start:
|
||||
ARM_VECTORS
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ROCKCHIP_RK3399) && defined(CONFIG_SPL_BUILD)
|
||||
.space CONFIG_ROCKCHIP_SPL_RESERVE_IRAM /* space for the ATF data */
|
||||
|
|
|
@ -15,5 +15,11 @@
|
|||
#define BOOT_CHARGING (REBOOT_FLAG + 11)
|
||||
/* enter usb mass storage mode */
|
||||
#define BOOT_UMS (REBOOT_FLAG + 12)
|
||||
/* enter bootrom download mode */
|
||||
#define BOOT_BROM_DOWNLOAD 0xEF08A53C
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
int setup_boot_mode(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* (C) Copyright 2017 Heiko Stuebner <heiko@sntech.de>
|
||||
* (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
@ -14,15 +15,30 @@
|
|||
extern u32 SAVE_SP_ADDR;
|
||||
|
||||
/**
|
||||
* Hand control back to the bootrom to load another
|
||||
* boot stage.
|
||||
* back_to_bootrom() - return to bootrom (for TPL/SPL), passing a
|
||||
* result code
|
||||
*
|
||||
* Transfer control back to the Rockchip BROM, restoring necessary
|
||||
* register context and passing a command/result code to the BROM
|
||||
* to instruct its next actions (e.g. continue boot sequence, enter
|
||||
* download mode, ...).
|
||||
*
|
||||
* This function does not return.
|
||||
*
|
||||
* @brom_cmd: indicates how the bootrom should continue the boot
|
||||
* sequence (e.g. load the next stage)
|
||||
*/
|
||||
void back_to_bootrom(void);
|
||||
enum rockchip_bootrom_cmd {
|
||||
/*
|
||||
* These can not start at 0, as 0 has a special meaning
|
||||
* for setjmp().
|
||||
*/
|
||||
|
||||
/**
|
||||
* Assembler component for the above (do not call this directly)
|
||||
*/
|
||||
void _back_to_bootrom_s(void);
|
||||
BROM_BOOT_NEXTSTAGE = 1, /* continue boot-sequence */
|
||||
BROM_BOOT_ENTER_DNL, /* have BROM enter download-mode */
|
||||
};
|
||||
|
||||
void back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd);
|
||||
|
||||
/**
|
||||
* Boot-device identifiers as used by the BROM
|
||||
|
|
|
@ -39,6 +39,11 @@ static inline int rk_pll_id(enum rk_clk_id clk_id)
|
|||
return clk_id - 1;
|
||||
}
|
||||
|
||||
struct sysreset_reg {
|
||||
unsigned int glb_srst_fst_value;
|
||||
unsigned int glb_srst_snd_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* clk_get_divisor() - Calculate the required clock divisior
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* (C) Copyright 2016
|
||||
* Alexander Graf <agraf@suse.de>
|
||||
* (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
|
||||
* (C) Copyright 2016 Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
@ -8,89 +8,21 @@
|
|||
#ifndef _SETJMP_H_
|
||||
#define _SETJMP_H_ 1
|
||||
|
||||
/*
|
||||
* This really should be opaque, but the EFI implementation wrongly
|
||||
* assumes that a 'struct jmp_buf_data' is defined.
|
||||
*/
|
||||
struct jmp_buf_data {
|
||||
ulong target;
|
||||
ulong regs[5];
|
||||
int ret;
|
||||
#if defined(__aarch64__)
|
||||
u64 regs[13];
|
||||
#else
|
||||
u32 regs[10]; /* r4-r9, sl, fp, sp, lr */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct jmp_buf_data jmp_buf[1];
|
||||
|
||||
static inline int setjmp(jmp_buf jmp)
|
||||
{
|
||||
jmp->ret = 0;
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
asm volatile(
|
||||
"adr x1, jmp_target\n"
|
||||
"str x1, %0\n"
|
||||
"stp x26, x27, %1\n"
|
||||
"stp x28, x29, %2\n"
|
||||
"mov x1, sp\n"
|
||||
"str x1, %3\n"
|
||||
"jmp_target: "
|
||||
: "=m" (jmp->target), "=m" (jmp->regs[0]),
|
||||
"=m" (jmp->regs[2]), "=m" (jmp->regs[4])
|
||||
:
|
||||
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
|
||||
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
|
||||
"x16", "x17", "x18", "x19", "x20", "x21", "x22",
|
||||
"x23", "x24", "x25", /* x26, x27, x28, x29, sp */
|
||||
"x30", "cc", "memory");
|
||||
#else
|
||||
asm volatile(
|
||||
#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
|
||||
".align 2\n"
|
||||
"adr r0, jmp_target\n"
|
||||
"add r0, r0, $1\n"
|
||||
#else
|
||||
"adr r0, jmp_target\n"
|
||||
#endif
|
||||
"mov r1, %0\n"
|
||||
"mov r2, sp\n"
|
||||
"stm r1!, {r0, r2, r4, r5, r6, r7}\n"
|
||||
".align 2\n"
|
||||
"jmp_target: \n"
|
||||
:
|
||||
: "l" (&jmp->target)
|
||||
: "r0", "r1", "r2", "r3", /* "r4", "r5", "r6", "r7", */
|
||||
"r8", "r9", "r10", "r11", /* sp, */ "ip", "lr",
|
||||
"cc", "memory");
|
||||
#endif
|
||||
|
||||
return jmp->ret;
|
||||
}
|
||||
|
||||
static inline __noreturn void longjmp(jmp_buf jmp, int ret)
|
||||
{
|
||||
jmp->ret = ret;
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
asm volatile(
|
||||
"ldr x0, %0\n"
|
||||
"ldr x1, %3\n"
|
||||
"mov sp, x1\n"
|
||||
"ldp x26, x27, %1\n"
|
||||
"ldp x28, x25, %2\n"
|
||||
"mov x29, x25\n"
|
||||
"br x0\n"
|
||||
:
|
||||
: "m" (jmp->target), "m" (jmp->regs[0]), "m" (jmp->regs[2]),
|
||||
"m" (jmp->regs[4])
|
||||
: "x0", "x1", "x25", "x26", "x27", "x28");
|
||||
#else
|
||||
asm volatile(
|
||||
"mov r1, %0\n"
|
||||
"ldm r1!, {r0, r2, r4, r5, r6, r7}\n"
|
||||
"mov sp, r2\n"
|
||||
"bx r0\n"
|
||||
:
|
||||
: "l" (&jmp->target)
|
||||
: "r1");
|
||||
#endif
|
||||
|
||||
while (1) { }
|
||||
}
|
||||
|
||||
int setjmp(jmp_buf jmp);
|
||||
void longjmp(jmp_buf jmp, int ret);
|
||||
|
||||
#endif /* _SETJMP_H_ */
|
||||
|
|
|
@ -332,37 +332,6 @@ void psci_arch_init(void);
|
|||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/**
|
||||
* save_boot_params() - Save boot parameters before starting reset sequence
|
||||
*
|
||||
* If you provide this function it will be called immediately U-Boot starts,
|
||||
* both for SPL and U-Boot proper.
|
||||
*
|
||||
* All registers are unchanged from U-Boot entry. No registers need be
|
||||
* preserved.
|
||||
*
|
||||
* This is not a normal C function. There is no stack. Return by branching to
|
||||
* save_boot_params_ret.
|
||||
*
|
||||
* void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3);
|
||||
*/
|
||||
|
||||
/**
|
||||
* save_boot_params_ret() - Return from save_boot_params()
|
||||
*
|
||||
* If you provide save_boot_params(), then you should jump back to this
|
||||
* function when done. Try to preserve all registers.
|
||||
*
|
||||
* If your implementation of save_boot_params() is in C then it is acceptable
|
||||
* to simply call save_boot_params_ret() at the end of your function. Since
|
||||
* there is no link register set up, you cannot just exit the function. U-Boot
|
||||
* will return to the (initialised) value of lr, and likely crash/hang.
|
||||
*
|
||||
* If your implementation of save_boot_params() is in assembler then you
|
||||
* should use 'b' or 'bx' to return to save_boot_params_ret.
|
||||
*/
|
||||
void save_boot_params_ret(void);
|
||||
|
||||
#ifdef CONFIG_ARMV7_LPAE
|
||||
void switch_to_hypervisor_ret(void);
|
||||
#endif
|
||||
|
@ -555,6 +524,37 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop);
|
|||
#endif /* CONFIG_ARM64 */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/**
|
||||
* save_boot_params() - Save boot parameters before starting reset sequence
|
||||
*
|
||||
* If you provide this function it will be called immediately U-Boot starts,
|
||||
* both for SPL and U-Boot proper.
|
||||
*
|
||||
* All registers are unchanged from U-Boot entry. No registers need be
|
||||
* preserved.
|
||||
*
|
||||
* This is not a normal C function. There is no stack. Return by branching to
|
||||
* save_boot_params_ret.
|
||||
*
|
||||
* void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3);
|
||||
*/
|
||||
|
||||
/**
|
||||
* save_boot_params_ret() - Return from save_boot_params()
|
||||
*
|
||||
* If you provide save_boot_params(), then you should jump back to this
|
||||
* function when done. Try to preserve all registers.
|
||||
*
|
||||
* If your implementation of save_boot_params() is in C then it is acceptable
|
||||
* to simply call save_boot_params_ret() at the end of your function. Since
|
||||
* there is no link register set up, you cannot just exit the function. U-Boot
|
||||
* will return to the (initialised) value of lr, and likely crash/hang.
|
||||
*
|
||||
* If your implementation of save_boot_params() is in assembler then you
|
||||
* should use 'b' or 'bx' to return to save_boot_params_ret.
|
||||
*/
|
||||
void save_boot_params_ret(void);
|
||||
|
||||
/**
|
||||
* Change the cache settings for a region.
|
||||
*
|
||||
|
|
|
@ -17,6 +17,12 @@ else
|
|||
obj-y += vectors.o crt0.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_ARM64
|
||||
obj-y += setjmp_aarch64.o
|
||||
else
|
||||
obj-y += setjmp.o
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
ifdef CONFIG_ARM64
|
||||
obj-y += relocate_64.o
|
||||
|
|
37
arch/arm/lib/setjmp.S
Normal file
37
arch/arm/lib/setjmp.S
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* (C) 2017 Theobroma Systems Design und Consulting GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.pushsection .text.setjmp, "ax"
|
||||
ENTRY(setjmp)
|
||||
/*
|
||||
* A subroutine must preserve the contents of the registers
|
||||
* r4-r8, r10, r11 (v1-v5, v7 and v8) and SP (and r9 in PCS
|
||||
* variants that designate r9 as v6).
|
||||
*/
|
||||
mov ip, sp
|
||||
stm a1, {v1-v8, ip, lr}
|
||||
mov a1, #0
|
||||
bx lr
|
||||
ENDPROC(setjmp)
|
||||
.popsection
|
||||
|
||||
.pushsection .text.longjmp, "ax"
|
||||
ENTRY(longjmp)
|
||||
ldm a1, {v1-v8, ip, lr}
|
||||
mov sp, ip
|
||||
mov a1, a2
|
||||
/* If we were passed a return value of zero, return one instead */
|
||||
cmp a1, #0
|
||||
bne 1f
|
||||
mov a1, #1
|
||||
1:
|
||||
bx lr
|
||||
ENDPROC(longjmp)
|
||||
.popsection
|
42
arch/arm/lib/setjmp_aarch64.S
Normal file
42
arch/arm/lib/setjmp_aarch64.S
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* (C) 2017 Theobroma Systems Design und Consulting GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <asm/macro.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
.pushsection .text.setjmp, "ax"
|
||||
ENTRY(setjmp)
|
||||
/* Preserve all callee-saved registers and the SP */
|
||||
stp x19, x20, [x0,#0]
|
||||
stp x21, x22, [x0,#16]
|
||||
stp x23, x24, [x0,#32]
|
||||
stp x25, x26, [x0,#48]
|
||||
stp x27, x28, [x0,#64]
|
||||
stp x29, x30, [x0,#80]
|
||||
mov x2, sp
|
||||
str x2, [x0, #96]
|
||||
mov x0, #0
|
||||
ret
|
||||
ENDPROC(setjmp)
|
||||
.popsection
|
||||
|
||||
.pushsection .text.longjmp, "ax"
|
||||
ENTRY(longjmp)
|
||||
ldp x19, x20, [x0,#0]
|
||||
ldp x21, x22, [x0,#16]
|
||||
ldp x23, x24, [x0,#32]
|
||||
ldp x25, x26, [x0,#48]
|
||||
ldp x27, x28, [x0,#64]
|
||||
ldp x29, x30, [x0,#80]
|
||||
ldr x2, [x0,#96]
|
||||
mov sp, x2
|
||||
/* Move the return value in place, but return 1 if passed 0. */
|
||||
adds x0, xzr, x1
|
||||
csinc x0, x0, xzr, ne
|
||||
ret
|
||||
ENDPROC(longjmp)
|
||||
.popsection
|
|
@ -15,6 +15,22 @@
|
|||
|
||||
#include <config.h>
|
||||
|
||||
/*
|
||||
* A macro to allow insertion of an ARM exception vector either
|
||||
* for the non-boot0 case or by a boot0-header.
|
||||
*/
|
||||
.macro ARM_VECTORS
|
||||
b reset
|
||||
ldr pc, _undefined_instruction
|
||||
ldr pc, _software_interrupt
|
||||
ldr pc, _prefetch_abort
|
||||
ldr pc, _data_abort
|
||||
ldr pc, _not_used
|
||||
ldr pc, _irq
|
||||
ldr pc, _fiq
|
||||
.endm
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
|
@ -35,6 +51,23 @@
|
|||
|
||||
.section ".vectors", "ax"
|
||||
|
||||
#if defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK)
|
||||
/*
|
||||
* Various SoCs need something special and SoC-specific up front in
|
||||
* order to boot, allow them to set that in their boot0.h file and then
|
||||
* use it here.
|
||||
*
|
||||
* To allow a boot0 hook to insert a 'special' sequence after the vector
|
||||
* table (e.g. for the socfpga), the presence of a boot0 hook supresses
|
||||
* the below vector table and assumes that the vector table is filled in
|
||||
* by the boot0 hook. The requirements for a boot0 hook thus are:
|
||||
* (1) defines '_start:' as appropriate
|
||||
* (2) inserts the vector table using ARM_VECTORS as appropriate
|
||||
*/
|
||||
#include <asm/arch/boot0.h>
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
*
|
||||
|
@ -46,28 +79,11 @@
|
|||
*/
|
||||
|
||||
_start:
|
||||
|
||||
#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
|
||||
.word CONFIG_SYS_DV_NOR_BOOT_CFG
|
||||
#endif
|
||||
|
||||
b reset
|
||||
ldr pc, _undefined_instruction
|
||||
ldr pc, _software_interrupt
|
||||
ldr pc, _prefetch_abort
|
||||
ldr pc, _data_abort
|
||||
ldr pc, _not_used
|
||||
ldr pc, _irq
|
||||
ldr pc, _fiq
|
||||
|
||||
#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
/*
|
||||
* Various SoCs need something special and SoC-specific up front in
|
||||
* order to boot, allow them to set that in their boot0.h file and then
|
||||
* use it here.
|
||||
*/
|
||||
#include <asm/arch/boot0.h>
|
||||
#endif
|
||||
ARM_VECTORS
|
||||
#endif /* !defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) */
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
|
|
|
@ -16,9 +16,14 @@ config ROCKCHIP_RK3188
|
|||
select CPU_V7
|
||||
select SPL_BOARD_INIT if SPL
|
||||
select SUPPORT_SPL
|
||||
select SUPPORT_TPL
|
||||
select SPL
|
||||
select TPL
|
||||
select SPL_CLK
|
||||
select SPL_PINCTRL
|
||||
select SPL_REGMAP
|
||||
select SPL_SYSCON
|
||||
select SPL_RAM
|
||||
select SPL_DRIVERS_MISC_SUPPORT
|
||||
select SPL_ROCKCHIP_EARLYRETURN_TO_BROM
|
||||
select BOARD_LATE_INIT
|
||||
select ROCKCHIP_BROM_HELPER
|
||||
help
|
||||
|
@ -74,7 +79,6 @@ config ROCKCHIP_RK3368
|
|||
imply SPL_SEPARATE_BSS
|
||||
imply SPL_SERIAL_SUPPORT
|
||||
imply TPL_SERIAL_SUPPORT
|
||||
select ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
select DEBUG_UART_BOARD_INIT
|
||||
select SYS_NS16550
|
||||
help
|
||||
|
@ -112,8 +116,9 @@ config ROCKCHIP_RK3399
|
|||
select SPL_SEPARATE_BSS
|
||||
select SPL_SERIAL_SUPPORT
|
||||
select SPL_DRIVERS_MISC_SUPPORT
|
||||
select ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
select DEBUG_UART_BOARD_INIT
|
||||
select BOARD_LATE_INIT
|
||||
select ROCKCHIP_BROM_HELPER
|
||||
help
|
||||
The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
|
||||
and quad-core Cortex-A53.
|
||||
|
@ -149,6 +154,20 @@ config TPL_ROCKCHIP_BACK_TO_BROM
|
|||
SPL will return to the boot rom, which will then load the U-Boot
|
||||
binary to keep going on.
|
||||
|
||||
config ROCKCHIP_BOOT_MODE_REG
|
||||
hex "Rockchip boot mode flag register address"
|
||||
default 0x200081c8 if ROCKCHIP_RK3036
|
||||
default 0x20004040 if ROCKCHIP_RK3188
|
||||
default 0x110005c8 if ROCKCHIP_RK322X
|
||||
default 0xff730094 if ROCKCHIP_RK3288
|
||||
default 0xff738200 if ROCKCHIP_RK3368
|
||||
default 0xff320300 if ROCKCHIP_RK3399
|
||||
default 0x10300580 if ROCKCHIP_RV1108
|
||||
default 0
|
||||
help
|
||||
The Soc will enter to different boot mode(defined in asm/arch/boot_mode.h)
|
||||
according to the value from this register.
|
||||
|
||||
config ROCKCHIP_SPL_RESERVE_IRAM
|
||||
hex "Size of IRAM reserved in SPL"
|
||||
default 0x4000
|
||||
|
@ -160,6 +179,34 @@ config ROCKCHIP_SPL_RESERVE_IRAM
|
|||
config ROCKCHIP_BROM_HELPER
|
||||
bool
|
||||
|
||||
config SPL_ROCKCHIP_EARLYRETURN_TO_BROM
|
||||
bool "SPL requires early-return (for RK3188-style BROM) to BROM"
|
||||
depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
help
|
||||
Some Rockchip BROM variants (e.g. on the RK3188) load the
|
||||
first stage in segments and enter multiple times. E.g. on
|
||||
the RK3188, the first 1KB of the first stage are loaded
|
||||
first and entered; after returning to the BROM, the
|
||||
remainder of the first stage is loaded, but the BROM
|
||||
re-enters at the same address/to the same code as previously.
|
||||
|
||||
This enables support code in the BOOT0 hook for the SPL stage
|
||||
to allow multiple entries.
|
||||
|
||||
config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
|
||||
bool "TPL requires early-return (for RK3188-style BROM) to BROM"
|
||||
depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK
|
||||
help
|
||||
Some Rockchip BROM variants (e.g. on the RK3188) load the
|
||||
first stage in segments and enter multiple times. E.g. on
|
||||
the RK3188, the first 1KB of the first stage are loaded
|
||||
first and entered; after returning to the BROM, the
|
||||
remainder of the first stage is loaded, but the BROM
|
||||
re-enters at the same address/to the same code as previously.
|
||||
|
||||
This enables support code in the BOOT0 hook for the TPL stage
|
||||
to allow multiple entries.
|
||||
|
||||
config SPL_MMC_SUPPORT
|
||||
default y if !SPL_ROCKCHIP_BACK_TO_BROM
|
||||
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
# this may have entered from ATF with the stack-pointer pointing to
|
||||
# inaccessible/protected memory (and the bootrom-helper assumes that
|
||||
# the stack-pointer is valid before switching to the U-Boot stack).
|
||||
obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o
|
||||
obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o
|
||||
obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
|
||||
obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
|
||||
|
||||
obj-tpl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o
|
||||
obj-tpl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-tpl.o
|
||||
obj-tpl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-tpl.o
|
||||
|
||||
|
@ -23,10 +22,16 @@ obj-spl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-spl.o spl-boot-order.o
|
|||
obj-spl-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-spl.o spl-boot-order.o
|
||||
|
||||
ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
|
||||
|
||||
ifneq ($(CONFIG_ROCKCHIP_BOOT_MODE_REG),0)
|
||||
obj-y += boot_mode.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x-board.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
|
||||
|
|
76
arch/arm/mach-rockchip/boot_mode.c
Normal file
76
arch/arm/mach-rockchip/boot_mode.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <adc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/boot_mode.h>
|
||||
|
||||
void set_back_to_bootrom_dnl_flag(void)
|
||||
{
|
||||
writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
|
||||
}
|
||||
|
||||
/*
|
||||
* detect download key status by adc, most rockchip
|
||||
* based boards use adc sample the download key status,
|
||||
* but there are also some use gpio. So it's better to
|
||||
* make this a weak function that can be override by
|
||||
* some special boards.
|
||||
*/
|
||||
#define KEY_DOWN_MIN_VAL 0
|
||||
#define KEY_DOWN_MAX_VAL 30
|
||||
|
||||
__weak int rockchip_dnl_key_pressed(void)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if (adc_channel_single_shot("saradc", 1, &val)) {
|
||||
pr_err("%s: adc_channel_single_shot fail!\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void rockchip_dnl_mode_check(void)
|
||||
{
|
||||
if (rockchip_dnl_key_pressed()) {
|
||||
printf("download key pressed, entering download mode...");
|
||||
set_back_to_bootrom_dnl_flag();
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int setup_boot_mode(void)
|
||||
{
|
||||
void *reg = (void *)CONFIG_ROCKCHIP_BOOT_MODE_REG;
|
||||
int boot_mode = readl(reg);
|
||||
|
||||
rockchip_dnl_mode_check();
|
||||
|
||||
boot_mode = readl(reg);
|
||||
debug("%s: boot mode 0x%08x\n", __func__, boot_mode);
|
||||
|
||||
/* Clear boot mode */
|
||||
writel(BOOT_NORMAL, reg);
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_FASTBOOT:
|
||||
debug("%s: enter fastboot!\n", __func__);
|
||||
env_set("preboot", "setenv preboot; fastboot usb0");
|
||||
break;
|
||||
case BOOT_UMS:
|
||||
debug("%s: enter UMS!\n", __func__);
|
||||
env_set("preboot", "setenv preboot; ums mmc 0");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -6,11 +6,104 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <asm/arch/bootrom.h>
|
||||
#include <asm/arch/boot_mode.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/setjmp.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
void back_to_bootrom(void)
|
||||
/*
|
||||
* Force the jmp_buf to the data-section, as .bss will not be valid
|
||||
* when save_boot_params is invoked.
|
||||
*/
|
||||
static jmp_buf brom_ctx __section(".data");
|
||||
|
||||
static void _back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd)
|
||||
{
|
||||
longjmp(brom_ctx, brom_cmd);
|
||||
}
|
||||
|
||||
void back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd)
|
||||
{
|
||||
#if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT)
|
||||
puts("Returning to boot ROM...\n");
|
||||
#endif
|
||||
_back_to_bootrom_s();
|
||||
_back_to_bootrom(brom_cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* we back to bootrom download mode if get a
|
||||
* BOOT_BROM_DOWNLOAD flag in boot mode register
|
||||
*
|
||||
* note: the boot mode register is configured by
|
||||
* application(next stage bootloader, kernel, etc),
|
||||
* and the bootrom never check this register, so we need
|
||||
* to check it and back to bootrom at very early bootstage(before
|
||||
* some basic configurations(such as interrupts) been
|
||||
* changed by TPL/SPL, as the bootrom download operation
|
||||
* relys on many default settings(such as interrupts) by
|
||||
* it's self.
|
||||
*/
|
||||
static bool check_back_to_brom_dnl_flag(void)
|
||||
{
|
||||
u32 boot_mode;
|
||||
|
||||
if (CONFIG_ROCKCHIP_BOOT_MODE_REG) {
|
||||
boot_mode = readl(CONFIG_ROCKCHIP_BOOT_MODE_REG);
|
||||
if (boot_mode == BOOT_BROM_DOWNLOAD) {
|
||||
writel(0, CONFIG_ROCKCHIP_BOOT_MODE_REG);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* All Rockchip BROM implementations enter with a valid stack-pointer,
|
||||
* so this can safely be implemented in C (providing a single
|
||||
* implementation both for ARMv7 and AArch64).
|
||||
*/
|
||||
int save_boot_params(void)
|
||||
{
|
||||
int ret = setjmp(brom_ctx);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
if (check_back_to_brom_dnl_flag())
|
||||
_back_to_bootrom(BROM_BOOT_ENTER_DNL);
|
||||
/*
|
||||
* This is the initial pass through this function
|
||||
* (i.e. saving the context), setjmp just setup up the
|
||||
* brom_ctx: transfer back into the startup-code at
|
||||
* 'save_boot_params_ret' and let the compiler know
|
||||
* that this will not return.
|
||||
*/
|
||||
save_boot_params_ret();
|
||||
while (true)
|
||||
/* does not return */;
|
||||
break;
|
||||
|
||||
case BROM_BOOT_NEXTSTAGE:
|
||||
/*
|
||||
* To instruct the BROM to boot the next stage, we
|
||||
* need to return 0 to it: i.e. we need to rewrite
|
||||
* the return code once more.
|
||||
*/
|
||||
ret = 0;
|
||||
break;
|
||||
case BROM_BOOT_ENTER_DNL:
|
||||
/*
|
||||
* A non-zero return value will instruct the BROM enter
|
||||
* download mode.
|
||||
*/
|
||||
ret = 1;
|
||||
break;
|
||||
default:
|
||||
#if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT)
|
||||
puts("FATAL: unexpected command to back_to_bootrom()\n");
|
||||
#endif
|
||||
hang();
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ void board_init_f(ulong dummy)
|
|||
sdram_init();
|
||||
|
||||
/* return to maskrom */
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
}
|
||||
|
||||
/* Place Holders */
|
||||
|
|
|
@ -19,30 +19,6 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define GRF_BASE 0x20008000
|
||||
|
||||
static void setup_boot_mode(void)
|
||||
{
|
||||
struct rk3036_grf *const grf = (void *)GRF_BASE;
|
||||
int boot_mode = readl(&grf->os_reg[4]);
|
||||
|
||||
debug("boot mode %x.\n", boot_mode);
|
||||
|
||||
/* Clear boot mode */
|
||||
writel(BOOT_NORMAL, &grf->os_reg[4]);
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_FASTBOOT:
|
||||
printf("enter fastboot!\n");
|
||||
env_set("preboot", "setenv preboot; fastboot usb0");
|
||||
break;
|
||||
case BOOT_UMS:
|
||||
printf("enter UMS!\n");
|
||||
env_set("preboot", "setenv preboot; ums mmc 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__weak int rk_board_late_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -101,7 +101,6 @@ static int setup_arm_clock(void)
|
|||
void board_init_f(ulong dummy)
|
||||
{
|
||||
struct udevice *pinctrl, *dev;
|
||||
struct rk3188_pmu *pmu;
|
||||
int ret;
|
||||
|
||||
/* Example code showing how to enable the debug UART on RK3188 */
|
||||
|
@ -145,15 +144,6 @@ void board_init_f(ulong dummy)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recover the bootrom's stackpointer.
|
||||
* For whatever reason needs to run after rockchip_get_clk.
|
||||
*/
|
||||
pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
|
||||
if (IS_ERR(pmu))
|
||||
pr_err("pmu syscon returned %ld\n", PTR_ERR(pmu));
|
||||
SAVE_SP_ADDR = readl(&pmu->sys_reg[2]);
|
||||
|
||||
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
|
||||
if (ret) {
|
||||
debug("Pinctrl init failed: %d\n", ret);
|
||||
|
@ -168,7 +158,7 @@ void board_init_f(ulong dummy)
|
|||
|
||||
setup_arm_clock();
|
||||
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -229,7 +219,7 @@ void spl_board_init(void)
|
|||
|
||||
preloader_console_init();
|
||||
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
#endif
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <spl.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/bootrom.h>
|
||||
#include <asm/arch/pmu_rk3188.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* track how often we were entered */
|
||||
static int rk3188_num_entries __attribute__ ((section(".data")));
|
||||
|
||||
#define PMU_BASE 0x20004000
|
||||
#define SPL_ENTRY 0x10080C00
|
||||
|
||||
static void jump_to_spl(void)
|
||||
{
|
||||
typedef void __noreturn (*image_entry_noargs_t)(void);
|
||||
|
||||
struct rk3188_pmu * const pmu = (void *)PMU_BASE;
|
||||
image_entry_noargs_t tpl_entry =
|
||||
(image_entry_noargs_t)(unsigned long)SPL_ENTRY;
|
||||
|
||||
/* Store the SAVE_SP_ADDR in a location shared with SPL. */
|
||||
writel(SAVE_SP_ADDR, &pmu->sys_reg[2]);
|
||||
tpl_entry();
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
/* Example code showing how to enable the debug UART on RK3188 */
|
||||
#ifdef EARLY_UART
|
||||
#include <asm/arch/grf_rk3188.h>
|
||||
/* Enable early UART on the RK3188 */
|
||||
#define GRF_BASE 0x20008000
|
||||
struct rk3188_grf * const grf = (void *)GRF_BASE;
|
||||
|
||||
rk_clrsetreg(&grf->gpio1b_iomux,
|
||||
GPIO1B1_MASK << GPIO1B1_SHIFT |
|
||||
GPIO1B0_MASK << GPIO1B0_SHIFT,
|
||||
GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
|
||||
GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
|
||||
/*
|
||||
* Debug UART can be used from here if required:
|
||||
*
|
||||
* debug_uart_init();
|
||||
* printch('a');
|
||||
* printhex8(0x1234);
|
||||
* printascii("string");
|
||||
*/
|
||||
debug_uart_init();
|
||||
|
||||
printch('t');
|
||||
printch('p');
|
||||
printch('l');
|
||||
printch('-');
|
||||
printch(rk3188_num_entries + 1 + '0');
|
||||
printch('\n');
|
||||
#endif
|
||||
|
||||
rk3188_num_entries++;
|
||||
|
||||
if (rk3188_num_entries == 1) {
|
||||
/*
|
||||
* The original loader did some very basic integrity
|
||||
* checking at this point, but the remaining few bytes
|
||||
* could be used for any improvement making sense
|
||||
* really early on.
|
||||
*/
|
||||
|
||||
back_to_bootrom();
|
||||
} else {
|
||||
/*
|
||||
* TPL part of the loader should now wait for us
|
||||
* at offset 0xC00 in the sram. Should never return
|
||||
* from there.
|
||||
*/
|
||||
jump_to_spl();
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ int board_late_init(void)
|
|||
{
|
||||
struct rk3188_grf *grf;
|
||||
|
||||
setup_boot_mode();
|
||||
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
if (IS_ERR(grf)) {
|
||||
pr_err("grf syscon returned %ld\n", PTR_ERR(grf));
|
||||
|
|
|
@ -76,6 +76,6 @@ void board_init_f(ulong dummy)
|
|||
/* Disable the ddr secure region setting to make it non-secure */
|
||||
rk_clrreg(SGRF_DDR_CON0, 0x4000);
|
||||
#if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -16,30 +16,6 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define GRF_BASE 0x11000000
|
||||
|
||||
static void setup_boot_mode(void)
|
||||
{
|
||||
struct rk322x_grf *const grf = (void *)GRF_BASE;
|
||||
int boot_mode = readl(&grf->os_reg[0]);
|
||||
|
||||
debug("boot mode %x.\n", boot_mode);
|
||||
|
||||
/* Clear boot mode */
|
||||
writel(BOOT_NORMAL, &grf->os_reg[0]);
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_FASTBOOT:
|
||||
printf("enter fastboot!\n");
|
||||
env_set("preboot", "setenv preboot; fastboot usb0");
|
||||
break;
|
||||
case BOOT_UMS:
|
||||
printf("enter UMS!\n");
|
||||
env_set("preboot", "setenv preboot; ums mmc 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__weak int rk_board_late_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -216,7 +216,7 @@ void board_init_f(ulong dummy)
|
|||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,7 @@ void spl_board_init(void)
|
|||
|
||||
preloader_console_init();
|
||||
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
#endif
|
||||
return;
|
||||
err:
|
||||
|
|
|
@ -69,7 +69,7 @@ void board_init_f(ulong dummy)
|
|||
|
||||
void board_return_to_bootrom(void)
|
||||
{
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
}
|
||||
|
||||
u32 spl_boot_device(void)
|
||||
|
|
|
@ -23,31 +23,6 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define PMU_BASE 0xff730000
|
||||
|
||||
static void setup_boot_mode(void)
|
||||
{
|
||||
struct rk3288_pmu *const pmu = (void *)PMU_BASE;
|
||||
int boot_mode = readl(&pmu->sys_reg[0]);
|
||||
|
||||
debug("boot mode %x.\n", boot_mode);
|
||||
|
||||
/* Clear boot mode */
|
||||
writel(BOOT_NORMAL, &pmu->sys_reg[0]);
|
||||
|
||||
switch (boot_mode) {
|
||||
case BOOT_FASTBOOT:
|
||||
printf("enter fastboot!\n");
|
||||
env_set("preboot", "setenv preboot; fastboot usb0");
|
||||
break;
|
||||
case BOOT_UMS:
|
||||
printf("enter UMS!\n");
|
||||
env_set("preboot", "setenv preboot; if mmc dev 0;"
|
||||
"then ums mmc 0; else ums mmc 1;fi");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__weak int rk_board_late_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -148,7 +148,7 @@ void board_init_f(ulong dummy)
|
|||
|
||||
void board_return_to_bootrom(void)
|
||||
{
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
}
|
||||
|
||||
u32 spl_boot_device(void)
|
||||
|
|
|
@ -23,7 +23,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
void board_return_to_bootrom(void)
|
||||
{
|
||||
back_to_bootrom();
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
}
|
||||
|
||||
static const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
|
||||
|
|
14
arch/arm/mach-rockchip/rk3399-board.c
Normal file
14
arch/arm/mach-rockchip/rk3399-board.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/boot_mode.h>
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
setup_boot_mode();
|
||||
return 0;
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
|
||||
* (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#if defined(CONFIG_ARM64)
|
||||
.globl SAVE_SP_ADDR
|
||||
SAVE_SP_ADDR:
|
||||
.quad 0
|
||||
|
||||
ENTRY(save_boot_params)
|
||||
sub sp, sp, #0x60
|
||||
stp x29, x30, [sp, #0x50]
|
||||
stp x27, x28, [sp, #0x40]
|
||||
stp x25, x26, [sp, #0x30]
|
||||
stp x23, x24, [sp, #0x20]
|
||||
stp x21, x22, [sp, #0x10]
|
||||
stp x19, x20, [sp, #0]
|
||||
ldr x8, =SAVE_SP_ADDR
|
||||
mov x9, sp
|
||||
str x9, [x8]
|
||||
b save_boot_params_ret /* back to my caller */
|
||||
ENDPROC(save_boot_params)
|
||||
|
||||
.globl _back_to_bootrom_s
|
||||
ENTRY(_back_to_bootrom_s)
|
||||
ldr x0, =SAVE_SP_ADDR
|
||||
ldr x0, [x0]
|
||||
mov sp, x0
|
||||
ldp x29, x30, [sp, #0x50]
|
||||
ldp x27, x28, [sp, #0x40]
|
||||
ldp x25, x26, [sp, #0x30]
|
||||
ldp x23, x24, [sp, #0x20]
|
||||
ldp x21, x22, [sp, #0x10]
|
||||
ldp x19, x20, [sp]
|
||||
add sp, sp, #0x60
|
||||
mov x0, xzr
|
||||
ret
|
||||
ENDPROC(_back_to_bootrom_s)
|
||||
#else
|
||||
.globl SAVE_SP_ADDR
|
||||
SAVE_SP_ADDR:
|
||||
.word 0
|
||||
|
||||
/*
|
||||
* void save_boot_params
|
||||
*
|
||||
* Save sp, lr, r1~r12
|
||||
*/
|
||||
ENTRY(save_boot_params)
|
||||
push {r1-r12, lr}
|
||||
ldr r0, =SAVE_SP_ADDR
|
||||
str sp, [r0]
|
||||
b save_boot_params_ret @ back to my caller
|
||||
ENDPROC(save_boot_params)
|
||||
|
||||
|
||||
.globl _back_to_bootrom_s
|
||||
ENTRY(_back_to_bootrom_s)
|
||||
ldr r0, =SAVE_SP_ADDR
|
||||
ldr sp, [r0]
|
||||
mov r0, #0
|
||||
pop {r1-r12, pc}
|
||||
ENDPROC(_back_to_bootrom_s)
|
||||
#endif
|
|
@ -7,6 +7,9 @@
|
|||
#ifndef __BOOT0_H
|
||||
#define __BOOT0_H
|
||||
|
||||
_start:
|
||||
ARM_VECTORS
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
.balignl 64,0xf33db33f;
|
||||
|
||||
|
|
|
@ -176,17 +176,17 @@ described above, but the image creation needs a bit more care.
|
|||
|
||||
The bootrom of rk3188 expects to find a small 1kb loader which returns
|
||||
control to the bootrom, after which it will load the real loader, which
|
||||
can then be up to 29kb in size and does the regular ddr init.
|
||||
can then be up to 29kb in size and does the regular ddr init. This is
|
||||
handled by a single image (built as the SPL stage) that tests whether
|
||||
it is handled for the first or second time via code executed from the
|
||||
boot0-hook.
|
||||
|
||||
Additionally the rk3188 requires everything the bootrom loads to be
|
||||
rc4-encrypted. Except for the very first stage the bootrom always reads
|
||||
and decodes 2kb pages, so files should be sized accordingly.
|
||||
|
||||
# copy tpl, pad to 1020 bytes and append spl
|
||||
cat tpl/u-boot-tpl.bin > tplspl.bin
|
||||
truncate -s 1020 tplspl.bin
|
||||
cat spl/u-boot-spl.bin >> tplspl.bin
|
||||
tools/mkimage -n rk3188 -T rksd -d tplspl.bin out
|
||||
tools/mkimage -n rk3188 -T rksd -d spl/u-boot-spl.bin out
|
||||
|
||||
# truncate, encode and append u-boot.bin
|
||||
truncate -s %2048 u-boot.bin
|
||||
|
|
|
@ -330,11 +330,22 @@ static int rk3036_clk_probe(struct udevice *dev)
|
|||
static int rk3036_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rk3036_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
debug("Warning: No RK3036 reset driver: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rk3036_cru,
|
||||
cru_glb_srst_fst_value);
|
||||
priv->glb_srst_snd_value = offsetof(struct rk3036_cru,
|
||||
cru_glb_srst_snd_value);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -573,11 +573,22 @@ static int rk3188_clk_probe(struct udevice *dev)
|
|||
static int rk3188_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rk3188_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
debug("Warning: No rk3188 reset driver: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rk3188_cru,
|
||||
cru_glb_srst_fst_value);
|
||||
priv->glb_srst_snd_value = offsetof(struct rk3188_cru,
|
||||
cru_glb_srst_snd_value);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -385,11 +385,22 @@ static int rk322x_clk_probe(struct udevice *dev)
|
|||
static int rk322x_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rk322x_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
debug("Warning: No RK322x reset driver: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rk322x_cru,
|
||||
cru_glb_srst_fst_value);
|
||||
priv->glb_srst_snd_value = offsetof(struct rk322x_cru,
|
||||
cru_glb_srst_snd_value);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -859,11 +859,22 @@ static int rk3288_clk_probe(struct udevice *dev)
|
|||
static int rk3288_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rk3288_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
debug("Warning: No RK3288 reset driver: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rk3288_cru,
|
||||
cru_glb_srst_fst_value);
|
||||
priv->glb_srst_snd_value = offsetof(struct rk3288_cru,
|
||||
cru_glb_srst_snd_value);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -597,11 +597,22 @@ static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
|
|||
static int rk3328_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rk3328_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
printf("Warning: No RK3328 reset driver: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rk3328_cru,
|
||||
glb_srst_fst_value);
|
||||
priv->glb_srst_snd_value = offsetof(struct rk3328_cru,
|
||||
glb_srst_snd_value);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -526,11 +526,22 @@ static int rk3368_clk_ofdata_to_platdata(struct udevice *dev)
|
|||
static int rk3368_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rk3368_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
pr_err("bind RK3368 reset driver failed: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rk3368_cru,
|
||||
glb_srst_fst_val);
|
||||
priv->glb_srst_snd_value = offsetof(struct rk3368_cru,
|
||||
glb_srst_snd_val);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1033,11 +1033,22 @@ static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
|
|||
static int rk3399_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rk3399_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
printf("Warning: No RK3399 reset driver: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rk3399_cru,
|
||||
glb_srst_fst_value);
|
||||
priv->glb_srst_snd_value = offsetof(struct rk3399_cru,
|
||||
glb_srst_snd_value);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -223,11 +223,22 @@ static int rv1108_clk_probe(struct udevice *dev)
|
|||
static int rv1108_clk_bind(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *sys_child;
|
||||
struct sysreset_reg *priv;
|
||||
|
||||
/* The reset driver does not have a device node, so bind it here */
|
||||
ret = device_bind_driver(gd->dm_root, "rv1108_sysreset", "reset", &dev);
|
||||
if (ret)
|
||||
pr_err("No Rv1108 reset driver: ret=%d\n", ret);
|
||||
ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
|
||||
&sys_child);
|
||||
if (ret) {
|
||||
debug("Warning: No sysreset driver: ret=%d\n", ret);
|
||||
} else {
|
||||
priv = malloc(sizeof(struct sysreset_reg));
|
||||
priv->glb_srst_fst_value = offsetof(struct rv1108_cru,
|
||||
glb_srst_fst_val);
|
||||
priv->glb_srst_snd_value = offsetof(struct rv1108_cru,
|
||||
glb_srst_snd_val);
|
||||
sys_child->priv = priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ static void rkspi_set_clk(struct rockchip_spi_priv *priv, uint speed)
|
|||
*/
|
||||
if (clk_div > 0xfffe) {
|
||||
clk_div = 0xfffe;
|
||||
debug("%s: can't divide down to %d hz (actual will be %d hz)\n",
|
||||
debug("%s: can't divide down to %d Hz (actual will be %d Hz)\n",
|
||||
__func__, speed, priv->input_rate / clk_div);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,16 +9,7 @@ obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
|
|||
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
|
||||
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
|
||||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
|
||||
endif
|
||||
obj-$(CONFIG_ROCKCHIP_RK3188) += sysreset_rk3188.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK322X) += sysreset_rk322x.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3288) += sysreset_rk3288.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3328) += sysreset_rk3328.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3368) += sysreset_rk3368.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
|
||||
obj-$(CONFIG_ROCKCHIP_RV1108) += sysreset_rv1108.o
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += sysreset_rockchip.o
|
||||
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
|
||||
obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o
|
||||
obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk3036.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rk3036_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rk3036_cru *cru = rockchip_get_cru();
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
writel(0xeca8, &cru->cru_glb_srst_snd_value);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rk3036_sysreset = {
|
||||
.request = rk3036_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rk3036) = {
|
||||
.name = "rk3036_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rk3036_sysreset,
|
||||
};
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <syscon.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk3188.h>
|
||||
#include <asm/arch/grf_rk3188.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rk3188_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rk3188_cru *cru = rockchip_get_cru();
|
||||
struct rk3188_grf *grf;
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
if (IS_ERR(grf))
|
||||
return -EPROTONOSUPPORT;
|
||||
|
||||
/*
|
||||
* warm-reset keeps the remap value,
|
||||
* so make sure it's disabled.
|
||||
*/
|
||||
rk_clrsetreg(&grf->soc_con0,
|
||||
NOC_REMAP_MASK << NOC_REMAP_SHIFT,
|
||||
0 << NOC_REMAP_SHIFT);
|
||||
|
||||
rk_clrreg(&cru->cru_mode_con, 0xffff);
|
||||
writel(0xeca8, &cru->cru_glb_srst_snd_value);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
rk_clrreg(&cru->cru_mode_con, 0xffff);
|
||||
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rk3188_sysreset = {
|
||||
.request = rk3188_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rk3188) = {
|
||||
.name = "rk3188_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rk3188_sysreset,
|
||||
};
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk322x.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rk322x_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rk322x_cru *cru = rockchip_get_cru();
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
writel(0xeca8, &cru->cru_glb_srst_snd_value);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rk322x_sysreset = {
|
||||
.request = rk322x_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rk322x) = {
|
||||
.name = "rk322x_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rk322x_sysreset,
|
||||
};
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk3288.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rk3288_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rk3288_cru *cru = rockchip_get_cru();
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
rk_clrreg(&cru->cru_mode_con, 0xffff);
|
||||
writel(0xeca8, &cru->cru_glb_srst_snd_value);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
rk_clrreg(&cru->cru_mode_con, 0xffff);
|
||||
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rk3288_sysreset = {
|
||||
.request = rk3288_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rk3288) = {
|
||||
.name = "rk3288_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rk3288_sysreset,
|
||||
};
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk3328.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rk3328_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rk3328_cru *cru = rockchip_get_cru();
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
writel(0xeca8, &cru->glb_srst_snd_value);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
writel(0xfdb9, &cru->glb_srst_fst_value);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rk3328_sysreset = {
|
||||
.request = rk3328_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rk3328) = {
|
||||
.name = "rk3328_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rk3328_sysreset,
|
||||
};
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk3368.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
static void rk3368_pll_enter_slow_mode(struct rk3368_cru *cru)
|
||||
{
|
||||
struct rk3368_pll *pll;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
pll = &cru->pll[i];
|
||||
rk_clrreg(&pll->con3, PLL_MODE_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
static int rk3368_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rk3368_cru *cru = rockchip_get_cru();
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
rk3368_pll_enter_slow_mode(cru);
|
||||
rk_clrsetreg(&cru->glb_rst_con, PMU_GLB_SRST_CTRL_MASK,
|
||||
PMU_RST_BY_SND_GLB_SRST << PMU_GLB_SRST_CTRL_SHIFT);
|
||||
writel(0xeca8, &cru->glb_srst_snd_val);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
rk3368_pll_enter_slow_mode(cru);
|
||||
rk_clrsetreg(&cru->glb_rst_con, PMU_GLB_SRST_CTRL_MASK,
|
||||
PMU_RST_BY_FST_GLB_SRST << PMU_GLB_SRST_CTRL_SHIFT);
|
||||
writel(0xfdb9, &cru->glb_srst_fst_val);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rk3368_sysreset = {
|
||||
.request = rk3368_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rk3368) = {
|
||||
.name = "rk3368_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rk3368_sysreset,
|
||||
};
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk3399.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rk3399_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rk3399_cru *cru = rockchip_get_cru();
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
writel(0xeca8, &cru->glb_srst_snd_value);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
writel(0xfdb9, &cru->glb_srst_fst_value);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rk3399_sysreset = {
|
||||
.request = rk3399_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rk3399) = {
|
||||
.name = "rk3399_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rk3399_sysreset,
|
||||
};
|
47
drivers/sysreset/sysreset_rockchip.c
Normal file
47
drivers/sysreset/sysreset_rockchip.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rk3328.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rockchip_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct sysreset_reg *offset = dev_get_priv(dev);
|
||||
unsigned long cru_base = (unsigned long)rockchip_get_cru();
|
||||
|
||||
if (IS_ERR_VALUE(cru_base))
|
||||
return (int)cru_base;
|
||||
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
writel(0xeca8, cru_base + offset->glb_srst_snd_value);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
writel(0xfdb9, cru_base + offset->glb_srst_fst_value);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rockchip_sysreset = {
|
||||
.request = rockchip_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rockchip) = {
|
||||
.name = "rockchip_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rockchip_sysreset,
|
||||
};
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2015 Rockchip Electronics Co., Ltd
|
||||
* Author: Andy Yan <andy.yan@rock-chips.com>
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <sysreset.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/cru_rv1108.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int rv1108_sysreset_request(struct udevice *dev, enum sysreset_t type)
|
||||
{
|
||||
struct rv1108_cru *cru = rockchip_get_cru();
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return PTR_ERR(cru);
|
||||
|
||||
switch (type) {
|
||||
case SYSRESET_WARM:
|
||||
writel(0xeca8, &cru->glb_srst_snd_val);
|
||||
break;
|
||||
case SYSRESET_COLD:
|
||||
writel(0xfdb9, &cru->glb_srst_fst_val);
|
||||
break;
|
||||
default:
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
static struct sysreset_ops rv1108_sysreset = {
|
||||
.request = rv1108_sysreset_request,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sysreset_rv1108) = {
|
||||
.name = "rv1108_sysreset",
|
||||
.id = UCLASS_SYSRESET,
|
||||
.ops = &rv1108_sysreset,
|
||||
};
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#include <configs/rk3368_common.h>
|
||||
|
||||
#define CONFIG_ENV_SIZE 0x2000
|
||||
|
||||
#define CONFIG_CONSOLE_SCROLL_LINES 10
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
#include <configs/rk3368_common.h>
|
||||
|
||||
#define CONFIG_ENV_SIZE 0x2000
|
||||
|
||||
#define CONFIG_CONSOLE_SCROLL_LINES 10
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#define CONFIG_SYS_INIT_SP_ADDR 0x60100000
|
||||
#define CONFIG_SYS_LOAD_ADDR 0x60800800
|
||||
#define CONFIG_SPL_STACK 0x10081fff
|
||||
#define CONFIG_SPL_TEXT_BASE 0x10081004
|
||||
#define CONFIG_SPL_TEXT_BASE 0x10081000
|
||||
|
||||
#define CONFIG_ROCKCHIP_MAX_INIT_SIZE (4 << 10)
|
||||
#define CONFIG_ROCKCHIP_CHIP_TAG "RK30"
|
||||
|
|
|
@ -36,23 +36,11 @@
|
|||
#define CONFIG_ROCKCHIP_MAX_INIT_SIZE (0x8000 - 0x800)
|
||||
#define CONFIG_ROCKCHIP_CHIP_TAG "RK31"
|
||||
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
#define CONFIG_SPL_TEXT_BASE 0x10080804
|
||||
/* tpl size 1kb - 4byte RK31 header */
|
||||
#define CONFIG_SPL_MAX_SIZE (0x400 - 0x4)
|
||||
#elif defined(CONFIG_SPL_BUILD)
|
||||
/* spl size 32kb sram - 2kb bootrom - 1kb spl */
|
||||
#define CONFIG_SPL_MAX_SIZE (0x8000 - 0xC00)
|
||||
#define CONFIG_SPL_TEXT_BASE 0x10080C00
|
||||
#define CONFIG_SPL_TEXT_BASE 0x10080800
|
||||
/* spl size 32kb sram - 2kb bootrom */
|
||||
#define CONFIG_SPL_MAX_SIZE (0x8000 - 0x800)
|
||||
#define CONFIG_SPL_FRAMEWORK 1
|
||||
#define CONFIG_SPL_CLK 1
|
||||
#define CONFIG_SPL_PINCTRL 1
|
||||
#define CONFIG_SPL_REGMAP 1
|
||||
#define CONFIG_SPL_SYSCON 1
|
||||
#define CONFIG_SPL_RAM 1
|
||||
#define CONFIG_SPL_DRIVERS_MISC_SUPPORT 1
|
||||
#define CONFIG_ROCKCHIP_SERIAL 1
|
||||
#endif
|
||||
|
||||
#define CONFIG_SPL_STACK 0x10087fff
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_TPL_BOOTROM_SUPPORT)
|
||||
# define CONFIG_SPL_TEXT_BASE 0x0
|
||||
#else
|
||||
# define CONFIG_SPL_TEXT_BASE 0xff704004
|
||||
# define CONFIG_SPL_TEXT_BASE 0xff704000
|
||||
#endif
|
||||
|
||||
/* MMC/SD IP block */
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <asm/arch/hardware.h>
|
||||
#include "rockchip-common.h"
|
||||
|
||||
#define CONFIG_ENV_SIZE 0x2000
|
||||
#define CONFIG_SYS_MALLOC_LEN (32 << 20)
|
||||
#define CONFIG_SYS_CBSIZE 1024
|
||||
#define CONFIG_SKIP_LOWLEVEL_INIT
|
||||
|
|
|
@ -58,9 +58,6 @@ struct header1_info {
|
|||
* @spl_hdr: Boot ROM requires a 4-bytes spl header
|
||||
* @spl_size: Spl size(include extra 4-bytes spl header)
|
||||
* @spl_rc4: RC4 encode the SPL binary (same key as header)
|
||||
* @spl_boot0: A new-style (ARM_SOC_BOOT0_HOOK) image that should
|
||||
* have the boot magic (e.g. 'RK33') written to its first
|
||||
* word.
|
||||
*/
|
||||
|
||||
struct spl_info {
|
||||
|
@ -68,19 +65,18 @@ struct spl_info {
|
|||
const char *spl_hdr;
|
||||
const uint32_t spl_size;
|
||||
const bool spl_rc4;
|
||||
const bool spl_boot0;
|
||||
};
|
||||
|
||||
static struct spl_info spl_infos[] = {
|
||||
{ "rk3036", "RK30", 0x1000, false, false },
|
||||
{ "rk3128", "RK31", 0x1800, false, false },
|
||||
{ "rk3188", "RK31", 0x8000 - 0x800, true, false },
|
||||
{ "rk322x", "RK32", 0x8000 - 0x1000, false, false },
|
||||
{ "rk3288", "RK32", 0x8000, false, false },
|
||||
{ "rk3328", "RK32", 0x8000 - 0x1000, false, false },
|
||||
{ "rk3368", "RK33", 0x8000 - 0x1000, false, true },
|
||||
{ "rk3399", "RK33", 0x30000 - 0x2000, false, true },
|
||||
{ "rv1108", "RK11", 0x1800, false, false},
|
||||
{ "rk3036", "RK30", 0x1000, false },
|
||||
{ "rk3128", "RK31", 0x1800, false },
|
||||
{ "rk3188", "RK31", 0x8000 - 0x800, true },
|
||||
{ "rk322x", "RK32", 0x8000 - 0x1000, false },
|
||||
{ "rk3288", "RK32", 0x8000, false },
|
||||
{ "rk3328", "RK32", 0x8000 - 0x1000, false },
|
||||
{ "rk3368", "RK33", 0x8000 - 0x1000, false },
|
||||
{ "rk3399", "RK33", 0x30000 - 0x2000, false },
|
||||
{ "rv1108", "RK11", 0x1800, false },
|
||||
};
|
||||
|
||||
static unsigned char rc4_key[16] = {
|
||||
|
@ -158,16 +154,6 @@ bool rkcommon_need_rc4_spl(struct image_tool_params *params)
|
|||
return info->spl_rc4;
|
||||
}
|
||||
|
||||
bool rkcommon_spl_is_boot0(struct image_tool_params *params)
|
||||
{
|
||||
struct spl_info *info = rkcommon_get_spl_info(params->imagename);
|
||||
|
||||
/*
|
||||
* info would not be NULL, because of we checked params before.
|
||||
*/
|
||||
return info->spl_boot0;
|
||||
}
|
||||
|
||||
static void rkcommon_set_header0(void *buf, uint file_size,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
|
@ -366,15 +352,12 @@ int rkcommon_vrec_header(struct image_tool_params *params,
|
|||
* have the first 4 bytes reserved for the spl_name). Reserving
|
||||
* these 4 bytes is done using the BOOT0_HOOK infrastructure.
|
||||
*
|
||||
* Depending on this, the header is either 0x800 (if this is a
|
||||
* 'boot0'-style payload, which has reserved 4 bytes at the
|
||||
* beginning for the 'spl_name' and expects us to overwrite
|
||||
* its first 4 bytes) or 0x804 bytes in length.
|
||||
* The header is always at 0x800 (as we now use a payload
|
||||
* prepadded using the boot0 hook for all targets): the first
|
||||
* 4 bytes of these images can safely be overwritten using the
|
||||
* boot magic.
|
||||
*/
|
||||
if (rkcommon_spl_is_boot0(params))
|
||||
tparams->header_size = RK_SPL_HDR_START;
|
||||
else
|
||||
tparams->header_size = RK_SPL_HDR_START + 4;
|
||||
tparams->header_size = RK_SPL_HDR_START;
|
||||
|
||||
/* Allocate, clear and install the header */
|
||||
tparams->hdr = malloc(tparams->header_size);
|
||||
|
|
Loading…
Reference in a new issue