mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
- Fix ARMv5/F1C100 FEL booting - Fix F1C100 reset - Introduce proper F1C100 boot method detection - Enable SPI booting for F1C100 Boot tested from FEL, SPI, SD card and eMMC (where applicable) on Pine64-LTS, Pine-H64, BananaPi M1, OrangePi Zero, LicheePi Nano(F1C100).
This commit is contained in:
commit
6d3c46ed0e
7 changed files with 69 additions and 37 deletions
|
@ -25,9 +25,9 @@ ENTRY(return_to_fel)
|
|||
mov sp, r0
|
||||
mov lr, r1
|
||||
ldr r0, =fel_stash
|
||||
ldr r1, [r0, #16]
|
||||
mcr p15, 0, r1, c1, c0, 0 @ Write CP15 Control Register
|
||||
ldr r1, [r0, #12]
|
||||
mcr p15, 0, r1, c1, c0, 0 @ Write CP15 SCTLR register
|
||||
ldr r1, [r0, #8]
|
||||
msr cpsr, r1 @ Write CPSR
|
||||
bx lr
|
||||
ENDPROC(return_to_fel)
|
||||
|
|
|
@ -160,6 +160,7 @@ enum sunxi_gpio_number {
|
|||
#define SUNXI_GPC_SDC2 3
|
||||
#define SUN6I_GPC_SDC3 4
|
||||
#define SUN50I_GPC_SPI0 4
|
||||
#define SUNIV_GPC_SPI0 2
|
||||
|
||||
#define SUNXI_GPD_LCD0 2
|
||||
#define SUNXI_GPD_LVDS0 3
|
||||
|
|
|
@ -19,6 +19,15 @@
|
|||
#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
|
||||
#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
|
||||
|
||||
/*
|
||||
* Values taken from the F1C200s BootROM stack
|
||||
* to determine where we booted from.
|
||||
*/
|
||||
#define SUNIV_BOOTED_FROM_MMC0 0xffff40f8
|
||||
#define SUNIV_BOOTED_FROM_NAND 0xffff4114
|
||||
#define SUNIV_BOOTED_FROM_SPI 0xffff4130
|
||||
#define SUNIV_BOOTED_FROM_MMC1 0xffff4150
|
||||
|
||||
#define is_boot0_magic(addr) (memcmp((void *)(addr), BOOT0_MAGIC, 8) == 0)
|
||||
|
||||
uint32_t sunxi_get_boot_device(void);
|
||||
|
|
|
@ -1038,7 +1038,7 @@ config SPL_STACK_R_ADDR
|
|||
|
||||
config SPL_SPI_SUNXI
|
||||
bool "Support for SPI Flash on Allwinner SoCs in SPL"
|
||||
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || MACH_SUN50I_H6
|
||||
depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || MACH_SUN50I_H6 || MACH_SUNIV
|
||||
help
|
||||
Enable support for SPI Flash. This option allows SPL to read from
|
||||
sunxi SPI Flash. It uses the same method as the boot ROM, so does
|
||||
|
|
|
@ -191,12 +191,48 @@ SPL_LOAD_IMAGE_METHOD("FEL", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
|
|||
|
||||
#define SUNXI_INVALID_BOOT_SOURCE -1
|
||||
|
||||
static int suniv_get_boot_source(void)
|
||||
{
|
||||
/* Get the last function call from BootROM's stack. */
|
||||
u32 brom_call = *(u32 *)(uintptr_t)(fel_stash.sp - 4);
|
||||
|
||||
/* translate SUNIV BootROM stack to standard SUNXI boot sources */
|
||||
switch (brom_call) {
|
||||
case SUNIV_BOOTED_FROM_MMC0:
|
||||
return SUNXI_BOOTED_FROM_MMC0;
|
||||
case SUNIV_BOOTED_FROM_SPI:
|
||||
return SUNXI_BOOTED_FROM_SPI;
|
||||
case SUNIV_BOOTED_FROM_MMC1:
|
||||
return SUNXI_BOOTED_FROM_MMC2;
|
||||
/* SPI NAND is not supported yet. */
|
||||
case SUNIV_BOOTED_FROM_NAND:
|
||||
return SUNXI_INVALID_BOOT_SOURCE;
|
||||
}
|
||||
/* If we get here something went wrong try to boot from FEL.*/
|
||||
printf("Unknown boot source from BROM: 0x%x\n", brom_call);
|
||||
return SUNXI_INVALID_BOOT_SOURCE;
|
||||
}
|
||||
|
||||
static int sunxi_get_boot_source(void)
|
||||
{
|
||||
/*
|
||||
* On the ARMv5 SoCs, the SPL header in SRAM is overwritten by the
|
||||
* exception vectors in U-Boot proper, so we won't find any
|
||||
* information there. Also the FEL stash is only valid in the SPL,
|
||||
* so we can't use that either. So if this is called from U-Boot
|
||||
* proper, just return MMC0 as a placeholder, for now.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNIV) &&
|
||||
!IS_ENABLED(CONFIG_SPL_BUILD))
|
||||
return SUNXI_BOOTED_FROM_MMC0;
|
||||
|
||||
if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
|
||||
return SUNXI_INVALID_BOOT_SOURCE;
|
||||
|
||||
return readb(SPL_ADDR + 0x28);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNIV))
|
||||
return suniv_get_boot_source();
|
||||
else
|
||||
return readb(SPL_ADDR + 0x28);
|
||||
}
|
||||
|
||||
/* The sunxi internal brom will try to loader external bootloader
|
||||
|
@ -276,36 +312,10 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
|
|||
return sector;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MACH_SUNIV
|
||||
/*
|
||||
* The suniv BROM does not pass the boot media type to SPL, so we try with the
|
||||
* boot sequence in BROM: mmc0->spinor->fail.
|
||||
* TODO: This has the slight chance of being wrong (invalid SPL signature,
|
||||
* but valid U-Boot legacy image on the SD card), but this should be rare.
|
||||
* It looks like we can deduce from some BROM state upon entering the SPL
|
||||
* (registers, SP, or stack itself) where the BROM was coming from and use
|
||||
* that here.
|
||||
*/
|
||||
void board_boot_order(u32 *spl_boot_list)
|
||||
{
|
||||
/*
|
||||
* See the comments above in sunxi_get_boot_device() for information
|
||||
* about FEL boot.
|
||||
*/
|
||||
if (!is_boot0_magic(SPL_ADDR + 4)) {
|
||||
spl_boot_list[0] = BOOT_DEVICE_BOARD;
|
||||
return;
|
||||
}
|
||||
|
||||
spl_boot_list[0] = BOOT_DEVICE_MMC1;
|
||||
spl_boot_list[1] = BOOT_DEVICE_SPI;
|
||||
}
|
||||
#else
|
||||
u32 spl_boot_device(void)
|
||||
{
|
||||
return sunxi_get_boot_device();
|
||||
}
|
||||
#endif
|
||||
|
||||
__weak void sunxi_sram_init(void)
|
||||
{
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
|
||||
#define SPI0_CLK_DIV_BY_2 0x1000
|
||||
#define SPI0_CLK_DIV_BY_4 0x1001
|
||||
#define SPI0_CLK_DIV_BY_32 0x100f
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@ -132,7 +133,8 @@ static uintptr_t spi0_base_address(void)
|
|||
if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
|
||||
return 0x05010000;
|
||||
|
||||
if (!is_sun6i_gen_spi())
|
||||
if (!is_sun6i_gen_spi() ||
|
||||
IS_ENABLED(CONFIG_MACH_SUNIV))
|
||||
return 0x01C05000;
|
||||
|
||||
return 0x01C68000;
|
||||
|
@ -156,11 +158,16 @@ static void spi0_enable_clock(void)
|
|||
if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
|
||||
setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
|
||||
|
||||
/* Divide by 4 */
|
||||
writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
|
||||
SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
|
||||
/* 24MHz from OSC24M */
|
||||
writel((1 << 31), CCM_SPI0_CLK);
|
||||
if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
|
||||
/* Divide by 32, clock source is AHB clock 200MHz */
|
||||
writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL);
|
||||
} else {
|
||||
/* Divide by 4 */
|
||||
writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
|
||||
SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
|
||||
/* 24MHz from OSC24M */
|
||||
writel((1 << 31), CCM_SPI0_CLK);
|
||||
}
|
||||
|
||||
if (is_sun6i_gen_spi()) {
|
||||
/* Enable SPI in the master mode and do a soft reset */
|
||||
|
@ -191,7 +198,8 @@ static void spi0_disable_clock(void)
|
|||
SUN4I_CTL_ENABLE);
|
||||
|
||||
/* Disable the SPI0 clock */
|
||||
writel(0, CCM_SPI0_CLK);
|
||||
if (!IS_ENABLED(CONFIG_MACH_SUNIV))
|
||||
writel(0, CCM_SPI0_CLK);
|
||||
|
||||
/* Close the SPI0 gate */
|
||||
if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
|
||||
|
@ -212,6 +220,8 @@ static void spi0_init(void)
|
|||
if (IS_ENABLED(CONFIG_MACH_SUN50I) ||
|
||||
IS_ENABLED(CONFIG_MACH_SUN50I_H6))
|
||||
pin_function = SUN50I_GPC_SPI0;
|
||||
else if (IS_ENABLED(CONFIG_MACH_SUNIV))
|
||||
pin_function = SUNIV_GPC_SPI0;
|
||||
|
||||
spi0_pinmux_setup(pin_function);
|
||||
spi0_enable_clock();
|
||||
|
|
|
@ -9,3 +9,5 @@ CONFIG_MACH_SUNIV=y
|
|||
CONFIG_DRAM_CLK=156
|
||||
CONFIG_DRAM_ZQ=0
|
||||
# CONFIG_VIDEO_SUNXI is not set
|
||||
CONFIG_SPL_SPI_SUNXI=y
|
||||
# CONFIG_SYSRESET is not set
|
||||
|
|
Loading…
Reference in a new issue