|
From 48be8001e507a0bd431b4f8186a95d11ddc6ee36 Mon Sep 17 00:00:00 2001 |
|
From: Andre Przywara <[email protected]> |
|
Date: Wed, 23 Nov 2016 00:35:01 +0000 |
|
Subject: [PATCH] sunxi: add SPL FEL button |
|
|
|
Some of the newer Allwinner boards that come with SPI flash soldered |
|
are missing an easy way to trigger the USB-OTG FEL boot mode. |
|
On most boards without eMMC FEL mode is entered when there is no SD card |
|
found, boards with eMMC typically feature a hardware FEL button. |
|
Now some boards like newer boards from OrangePi have no eMMC, but have a SPI |
|
flash chip soldered, which will be considered when booting the board. |
|
If there is now some valid eGON boot code on that SPI chip, it will |
|
never trigger FEL mode, unless one uses a magic uSD card which |
|
deliberately branches into the BootROM FEL routine. |
|
|
|
To avoid this rather involved way, we can emulate a FEL button in |
|
software, using any GPIO. Very early in the boot process this GPIO pin |
|
is configured as an input and sampled. If it is low, the code branches |
|
to the FEL routine, if not, normal booting proceeds. |
|
|
|
Add a simple routine which reads the configured GPIO and branches to FEL |
|
if needed. The exact GPIO to be used can be specified via Kconfig. |
|
|
|
Signed-off-by: Andre Przywara <[email protected]> |
|
--- |
|
arch/arm/mach-sunxi/Kconfig | 12 ++++++++++++ |
|
arch/arm/mach-sunxi/board.c | 33 +++++++++++++++++++++++++++++++++ |
|
include/configs/sunxi-common.h | 2 ++ |
|
3 files changed, 47 insertions(+) |
|
|
|
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig |
|
index 45dac4d445..8c93f3bb48 100644 |
|
--- a/arch/arm/mach-sunxi/Kconfig |
|
+++ b/arch/arm/mach-sunxi/Kconfig |
|
@@ -436,6 +436,18 @@ config SYS_BOARD |
|
config SYS_SOC |
|
default "sunxi" |
|
|
|
+config SUNXI_FEL_BUTTON_PIN |
|
+ string "FEL button pin" |
|
+ default "" |
|
+ depends on SUPPORT_SPL |
|
+ ---help--- |
|
+ Set a GPIO which acts as a FEL button. Very early in the SPL code |
|
+ this pin is briefly configured as an input and sampled. |
|
+ If it is pulled to GND, the code will jump to the BROM FEL routine. |
|
+ If it is floating or high, the boot process will proceed as normal. |
|
+ This takes a string in the format understood by sunxi_name_to_gpio, |
|
+ e.g. PH1 for pin 1 of port H. |
|
+ |
|
config UART0_PORT_F |
|
bool "UART0 on MicroSD breakout board" |
|
default n |
|
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c |
|
index 65b1ebd837..2ce074bbc4 100644 |
|
--- a/arch/arm/mach-sunxi/board.c |
|
+++ b/arch/arm/mach-sunxi/board.c |
|
@@ -151,10 +151,43 @@ static int spl_board_load_image(struct spl_image_info *spl_image, |
|
return 0; |
|
} |
|
SPL_LOAD_IMAGE_METHOD("FEL", 0, BOOT_DEVICE_BOARD, spl_board_load_image); |
|
+ |
|
+static void check_fel_button(void) |
|
+{ |
|
+#if defined(CONFIG_SUNXI_FEL_BUTTON_PIN) |
|
+ int mux, ret; |
|
+ uint32_t clockreg; |
|
+ int gpio = sunxi_name_to_gpio(CONFIG_SUNXI_FEL_BUTTON_PIN); |
|
+ |
|
+ if (gpio < 0) |
|
+ return; |
|
+ |
|
+ if (gpio >= SUNXI_GPL(0)) { |
|
+ clockreg = readl(SUNXI_PRCM_BASE + 0x28); |
|
+ writel(clockreg | 0x01, SUNXI_PRCM_BASE + 0x28); |
|
+ } |
|
+ |
|
+ mux = sunxi_gpio_get_cfgpin(gpio); |
|
+ sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT); |
|
+ ret = gpio_get_value(gpio); |
|
+ sunxi_gpio_set_cfgpin(gpio, mux); |
|
+ |
|
+ if (gpio >= SUNXI_GPL(0)) |
|
+ writel(clockreg, SUNXI_PRCM_BASE + 0x28); |
|
+ |
|
+ if (ret == 0) |
|
+ return_to_fel(fel_stash.sp, FEL_ENTRY_POINT); |
|
+#endif /* FEL_BUTTON_GPIO */ |
|
+} |
|
+#else |
|
+static void check_fel_button(void) |
|
+{ |
|
+} |
|
#endif |
|
|
|
void s_init(void) |
|
{ |
|
+ check_fel_button(); |
|
/* |
|
* Undocumented magic taken from boot0, without this DRAM |
|
* access gets messed up (seems cache related). |
|
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h |
|
index 4552418243..67006ea4d7 100644 |
|
--- a/include/configs/sunxi-common.h |
|
+++ b/include/configs/sunxi-common.h |
|
@@ -98,9 +98,11 @@ |
|
*/ |
|
#define CONFIG_SYS_INIT_RAM_ADDR 0x10000 |
|
#define CONFIG_SYS_INIT_RAM_SIZE 0x08000 /* FIXME: 40 KiB ? */ |
|
+#define FEL_ENTRY_POINT 0x00000020 |
|
#else |
|
#define CONFIG_SYS_INIT_RAM_ADDR 0x0 |
|
#define CONFIG_SYS_INIT_RAM_SIZE 0x8000 /* 32 KiB */ |
|
+#define FEL_ENTRY_POINT 0xffff0020 |
|
#endif |
|
|
|
#define CONFIG_SYS_INIT_SP_OFFSET \ |
|
-- |
|
2.14.1 |
@apritzel worked perfectly for me, thanks!