]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-rockchip/spl-boot-order.c
2 * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
4 * SPDX-License-Identifier: GPL-2.0+
12 #if CONFIG_IS_ENABLED(OF_CONTROL)
14 * spl_node_to_boot_device() - maps from a DT-node to a SPL boot device
15 * @node: of_offset of the node
17 * The SPL framework uses BOOT_DEVICE_... constants to identify its boot
18 * sources. These may take on a device-specific meaning, depending on
19 * what nodes are enabled in a DTS (e.g. BOOT_DEVICE_MMC1 may refer to
20 * different controllers/block-devices, depending on which SD/MMC controllers
21 * are enabled in any given DTS). This function maps from a DT-node back
22 * onto a BOOT_DEVICE_... constant, considering the currently active devices.
25 * -ENOENT, if no device matching the node could be found
26 * -ENOSYS, if the device matching the node can not be mapped onto a
27 * SPL boot device (e.g. the third MMC device)
28 * -1, for unspecified failures
29 * a positive integer (from the BOOT_DEVICE_... family) on succes.
32 static int spl_node_to_boot_device(int node
)
34 struct udevice
*parent
;
37 * This should eventually move into the SPL code, once SPL becomes
38 * aware of the block-device layer. Until then (and to avoid unneeded
39 * delays in getting this feature out, it lives at the board-level).
41 if (!uclass_get_device_by_of_offset(UCLASS_MMC
, node
, &parent
)) {
43 struct blk_desc
*desc
= NULL
;
45 for (device_find_first_child(parent
, &dev
);
47 device_find_next_child(&dev
)) {
48 if (device_get_uclass_id(dev
) == UCLASS_BLK
) {
49 desc
= dev_get_uclass_platdata(dev
);
57 switch (desc
->devnum
) {
59 return BOOT_DEVICE_MMC1
;
61 return BOOT_DEVICE_MMC2
;
68 * SPL doesn't differentiate SPI flashes, so we keep the detection
69 * brief and inaccurate... hopefully, the common SPL layer can be
70 * extended with awareness of the BLK layer (and matching OF_CONTROL)
73 if (!uclass_get_device_by_of_offset(UCLASS_SPI_FLASH
, node
, &parent
))
74 return BOOT_DEVICE_SPI
;
80 * board_spl_was_booted_from() - retrieves the of-path the SPL was loaded from
82 * To support a 'same-as-spl' specification in the search-order for the next
83 * stage, we need a SoC- or board-specific way to handshake with what 'came
84 * before us' (either a BROM or TPL stage) and map the info retrieved onto
88 * NULL, on failure or if the device could not be identified
89 * a of_path (a string), on success
91 __weak
const char *board_spl_was_booted_from(void)
93 debug("%s: no support for 'same-as-spl' for this board\n", __func__
);
97 void board_boot_order(u32
*spl_boot_list
)
99 const void *blob
= gd
->fdt_blob
;
100 int chosen_node
= fdt_path_offset(blob
, "/chosen");
107 if (chosen_node
< 0) {
108 debug("%s: /chosen not found, using spl_boot_device()\n",
110 spl_boot_list
[0] = spl_boot_device();
115 (conf
= fdt_stringlist_get(blob
, chosen_node
,
116 "u-boot,spl-boot-order", elem
, NULL
));
120 /* Handle the case of 'same device the SPL was loaded from' */
121 if (strncmp(conf
, "same-as-spl", 11) == 0) {
122 conf
= board_spl_was_booted_from();
127 /* First check if the list element is an alias */
128 alias
= fdt_get_alias(blob
, conf
);
132 /* Try to resolve the config item (or alias) as a path */
133 node
= fdt_path_offset(blob
, conf
);
135 debug("%s: could not find %s in FDT", __func__
, conf
);
139 /* Try to map this back onto SPL boot devices */
140 boot_device
= spl_node_to_boot_device(node
);
141 if (boot_device
< 0) {
142 debug("%s: could not map node @%x to a boot-device\n",
147 spl_boot_list
[idx
++] = boot_device
;
150 /* If we had no matches, fall back to spl_boot_device */
152 spl_boot_list
[0] = spl_boot_device();