Since the device-tree description of the peripherals contained on
daughtercards that can be mounted on the base-board is present in the
device-tree overlays for the respective daughtercards, in order to utilize
the functionality offered by the daughtercards, it is necessary to have the
device-tree overlay applied for the current stage bootloader by the previous
stage bootloader.

Two such use-cases are that of the PCI x2 Lane + USB 2.0 daughtercard
and the PCI x1 Lane + USB 3.0 daughtercard which provide PCI and USB
functionality. For U-Boot proper to detect and use them, SPL has to update
U-Boot proper's device-tree by applying the corresponding device-tree
overlay at runtime.

Hence, add support for this.

Signed-off-by: Siddharth Vadapalli <[email protected]>
---
 board/ti/am65x/evm.c | 76 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 69 insertions(+), 7 deletions(-)

diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index b35a9229033..1ee7ce5e30f 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -126,6 +126,14 @@ static int init_daughtercard_det_gpio(char *gpio_name, 
struct gpio_desc *desc)
        return dm_gpio_set_dir_flags(desc, GPIOD_IS_IN);
 }
 
+#ifdef CONFIG_XPL_BUILD
+/*
+ * Populated by probe_daughtercards() in SPL and used by
+ * board_spl_fit_append_fdt_skip().
+ */
+static char spl_detected_overlays[1024];
+#endif
+
 static int probe_daughtercards(void)
 {
        struct ti_am6_eeprom ep;
@@ -133,8 +141,7 @@ static int probe_daughtercards(void)
        char mac_addr[DAUGHTER_CARD_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
        u8 mac_addr_cnt;
        char name_overlays[1024] = { 0 };
-       int i, j;
-       int ret;
+       int ret, i;
 
        /*
         * Daughter card presence detection signal name to GPIO (via I2C I/O
@@ -242,9 +249,10 @@ static int probe_daughtercards(void)
                 * Populate any MAC addresses from daughtercard into the U-Boot
                 * environment, starting with a card-specific offset so we can
                 * have multiple cards contribute to the MAC pool in a well-
-                * defined manner.
+                * defined manner. Not applicable to SPL.
                 */
-               for (j = 0; j < mac_addr_cnt; j++) {
+#ifndef CONFIG_XPL_BUILD
+               for (int j = 0; j < mac_addr_cnt; j++) {
                        if (!is_valid_ethaddr((u8 *)mac_addr[j]))
                                continue;
 
@@ -252,6 +260,7 @@ static int probe_daughtercards(void)
                                                      cards[i].eth_offset + j,
                                                      (uchar *)mac_addr[j]);
                }
+#endif
 
                /*
                 * It has been observed that setting SERDES0 lane mux to USB 
prevents USB
@@ -283,13 +292,66 @@ static int probe_daughtercards(void)
                strcat(name_overlays, " ");
        }
 
+       if (!strlen(name_overlays))
+               return 0;
+
+#ifdef CONFIG_XPL_BUILD
+       /* Store for board_spl_fit_append_fdt_skip() */
+       strlcpy(spl_detected_overlays, name_overlays,
+               sizeof(spl_detected_overlays));
+       return 0;
+#else
        /* Apply device tree overlay(s) to the U-Boot environment, if any */
-       if (strlen(name_overlays))
-               return env_set("name_overlays", name_overlays);
+       return env_set("name_overlays", name_overlays);
+#endif
+}
+
+#ifdef CONFIG_XPL_BUILD
+void spl_board_init(void)
+{
+       /*
+        * Detect daughtercards to allow board_spl_fit_append_fdt_skip()
+        * to apply the overlays to U-Boot FIT image itself, allowing
+        * U-Boot proper to enable and use the peripherals on the
+        * daughtercards.
+        */
+       probe_daughtercards();
+}
+
+/*
+ * Mapping between FDTs in binman.dtsi and their corresponding Device-Tree
+ * overlays. Depending on the daughtercards detected, we conditionally
+ * apply the device-tree overlay's fdt if it is packaged.
+ */
+static const struct {
+       const char *fit_node;
+       const char *dtbo_name;
+} spl_fit_overlay_map[] = {
+       { "fdt-am654-pcie-usb2", "k3-am654-pcie-usb2.dtbo" },
+       { "fdt-am654-pcie-usb3", "k3-am654-pcie-usb3.dtbo" },
+};
+
+int board_spl_fit_append_fdt_skip(const char *name)
+{
+       int i;
 
+       /*
+        * For the overlays to be 'conditionally' applied, return 0 to apply 
them
+        * if the daughtercard corresponding to them was detected and return 1
+        * otherwise to skip applying the overlay.
+        */
+       for (i = 0; i < ARRAY_SIZE(spl_fit_overlay_map); i++) {
+               if (!strcmp(name, spl_fit_overlay_map[i].fit_node))
+                       return strstr(spl_detected_overlays,
+                                     spl_fit_overlay_map[i].dtbo_name) ? 0 : 1;
+       }
+
+       /* Any overlay not in the list of 'conditional' overlays is always 
applied */
        return 0;
 }
-#endif
+#endif /* CONFIG_XPL_BUILD */
+
+#endif /* CONFIG_TI_I2C_BOARD_DETECT */
 
 int board_late_init(void)
 {
-- 
2.51.1

Reply via email to