summaryrefslogtreecommitdiff
path: root/board/st/stm32mp2/stm32mp2.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/st/stm32mp2/stm32mp2.c')
-rw-r--r--board/st/stm32mp2/stm32mp2.c140
1 files changed, 139 insertions, 1 deletions
diff --git a/board/st/stm32mp2/stm32mp2.c b/board/st/stm32mp2/stm32mp2.c
index aa7dd31996e..2547f2e4bb7 100644
--- a/board/st/stm32mp2/stm32mp2.c
+++ b/board/st/stm32mp2/stm32mp2.c
@@ -5,16 +5,21 @@
#define LOG_CATEGORY LOGC_BOARD
+#include <button.h>
#include <config.h>
-#include <env.h>
+#include <env_internal.h>
#include <fdt_support.h>
+#include <led.h>
#include <log.h>
#include <misc.h>
+#include <mmc.h>
#include <asm/global_data.h>
+#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <dm/device.h>
#include <dm/ofnode.h>
#include <dm/uclass.h>
+#include <linux/delay.h>
/*
* Get a global data pointer
@@ -53,12 +58,140 @@ int checkboard(void)
return 0;
}
+static int get_led(struct udevice **dev, char *led_string)
+{
+ const char *led_name;
+ int ret;
+
+ led_name = ofnode_conf_read_str(led_string);
+ if (!led_name) {
+ log_debug("could not find %s config string\n", led_string);
+ return -ENOENT;
+ }
+ ret = led_get_by_label(led_name, dev);
+ if (ret) {
+ log_debug("get=%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int setup_led(enum led_state_t cmd)
+{
+ struct udevice *dev;
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(LED))
+ return 0;
+
+ ret = get_led(&dev, "u-boot,boot-led");
+ if (ret)
+ return ret;
+
+ ret = led_set_state(dev, cmd);
+ return ret;
+}
+
+static void check_user_button(void)
+{
+ struct udevice *button;
+ int i;
+
+ if (!IS_ENABLED(CONFIG_CMD_STM32PROG) || !IS_ENABLED(CONFIG_BUTTON))
+ return;
+
+ if (button_get_by_label("User-2", &button))
+ return;
+
+ for (i = 0; i < 21; ++i) {
+ if (button_get_state(button) != BUTTON_ON)
+ return;
+ if (i < 20)
+ mdelay(50);
+ }
+
+ log_notice("entering download mode...\n");
+ clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_STM32PROG);
+}
+
/* board dependent setup after realloc */
int board_init(void)
{
+ setup_led(LEDST_ON);
+ check_user_button();
+
return 0;
}
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+ u32 bootmode = get_bootmode();
+
+ if (prio)
+ return ENVL_UNKNOWN;
+
+ switch (bootmode & TAMP_BOOT_DEVICE_MASK) {
+ case BOOT_FLASH_SD:
+ case BOOT_FLASH_EMMC:
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_MMC))
+ return ENVL_MMC;
+ else
+ return ENVL_NOWHERE;
+
+ case BOOT_FLASH_NAND:
+ case BOOT_FLASH_SPINAND:
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_UBI))
+ return ENVL_UBI;
+ else
+ return ENVL_NOWHERE;
+
+ case BOOT_FLASH_NOR:
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH))
+ return ENVL_SPI_FLASH;
+ else
+ return ENVL_NOWHERE;
+ default:
+ return ENVL_NOWHERE;
+ }
+}
+
+int mmc_get_boot(void)
+{
+ struct udevice *dev;
+ u32 boot_mode = get_bootmode();
+ unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
+ char cmd[20];
+ const u32 sdmmc_addr[] = {
+ STM32_SDMMC1_BASE,
+ STM32_SDMMC2_BASE,
+ STM32_SDMMC3_BASE
+ };
+
+ if (instance > ARRAY_SIZE(sdmmc_addr))
+ return 0;
+
+ /* search associated sdmmc node in devicetree */
+ snprintf(cmd, sizeof(cmd), "mmc@%x", sdmmc_addr[instance]);
+ if (uclass_get_device_by_name(UCLASS_MMC, cmd, &dev)) {
+ log_err("mmc%d = %s not found in device tree!\n", instance, cmd);
+ return 0;
+ }
+
+ return dev_seq(dev);
+};
+
+int mmc_get_env_dev(void)
+{
+ const int mmc_env_dev = CONFIG_IS_ENABLED(ENV_IS_IN_MMC, (CONFIG_SYS_MMC_ENV_DEV), (-1));
+
+ if (mmc_env_dev >= 0)
+ return mmc_env_dev;
+
+ /* use boot instance to select the correct mmc device identifier */
+ return mmc_get_boot();
+}
+
int board_late_init(void)
{
const void *fdt_compat;
@@ -86,3 +219,8 @@ int board_late_init(void)
return 0;
}
+
+void board_quiesce_devices(void)
+{
+ setup_led(LEDST_OFF);
+}