summaryrefslogtreecommitdiff
path: root/arch/arm/mach-rockchip/spl-boot-order.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-rockchip/spl-boot-order.c')
-rw-r--r--arch/arm/mach-rockchip/spl-boot-order.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c
index 4f78c72720..843998dfdc 100644
--- a/arch/arm/mach-rockchip/spl-boot-order.c
+++ b/arch/arm/mach-rockchip/spl-boot-order.c
@@ -10,6 +10,25 @@
#include <spl.h>
#if CONFIG_IS_ENABLED(OF_CONTROL)
+/**
+ * spl_node_to_boot_device() - maps from a DT-node to a SPL boot device
+ * @node: of_offset of the node
+ *
+ * The SPL framework uses BOOT_DEVICE_... constants to identify its boot
+ * sources. These may take on a device-specific meaning, depending on
+ * what nodes are enabled in a DTS (e.g. BOOT_DEVICE_MMC1 may refer to
+ * different controllers/block-devices, depending on which SD/MMC controllers
+ * are enabled in any given DTS). This function maps from a DT-node back
+ * onto a BOOT_DEVICE_... constant, considering the currently active devices.
+ *
+ * Returns
+ * -ENOENT, if no device matching the node could be found
+ * -ENOSYS, if the device matching the node can not be mapped onto a
+ * SPL boot device (e.g. the third MMC device)
+ * -1, for unspecified failures
+ * a positive integer (from the BOOT_DEVICE_... family) on succes.
+ */
+
static int spl_node_to_boot_device(int node)
{
struct udevice *parent;
@@ -57,6 +76,24 @@ static int spl_node_to_boot_device(int node)
return -1;
}
+/**
+ * board_spl_was_booted_from() - retrieves the of-path the SPL was loaded from
+ *
+ * To support a 'same-as-spl' specification in the search-order for the next
+ * stage, we need a SoC- or board-specific way to handshake with what 'came
+ * before us' (either a BROM or TPL stage) and map the info retrieved onto
+ * a OF path.
+ *
+ * Returns
+ * NULL, on failure or if the device could not be identified
+ * a of_path (a string), on success
+ */
+__weak const char *board_spl_was_booted_from(void)
+{
+ debug("%s: no support for 'same-as-spl' for this board\n", __func__);
+ return NULL;
+}
+
void board_boot_order(u32 *spl_boot_list)
{
const void *blob = gd->fdt_blob;
@@ -78,8 +115,17 @@ void board_boot_order(u32 *spl_boot_list)
(conf = fdt_stringlist_get(blob, chosen_node,
"u-boot,spl-boot-order", elem, NULL));
elem++) {
+ const char *alias;
+
+ /* Handle the case of 'same device the SPL was loaded from' */
+ if (strncmp(conf, "same-as-spl", 11) == 0) {
+ conf = board_spl_was_booted_from();
+ if (!conf)
+ continue;
+ }
+
/* First check if the list element is an alias */
- const char *alias = fdt_get_alias(blob, conf);
+ alias = fdt_get_alias(blob, conf);
if (alias)
conf = alias;