// ...... /* khadas mcu part begin */ #define MCU_I2C_BUS_NUM 2 #define MCU_I2C_CHIP_ADDR 0x18 #define MCU_I2C_REG_BOOT_MODE 0x20 #define MCU_I2C_REG_BOOT_MODE_SPI 0x00 #define MCU_I2C_REG_BOOT_MODE_MMC 0x01 #define MCU_I2C_REG_BOOT_FLAG 0x92 #define MCU_I2C_REG_RESET_MODE 0x91 #define MCU_I2C_REG_BOOT_FLAG_NORMAL 0x00 #define MCU_I2C_REG_BOOT_FLAG_FUNC 0x01 #define MCU_I2C_REG_BOOT_FLAG_OOWOW 0x01 #define MCU_I2C_REG_BOOT_FLAG_SPI 0x02 #define MCU_I2C_REG_BOOT_FLAG_EMMC 0x03 #define MCU_I2C_REG_BOOT_FLAG_RESCUE 0x05 #define MCU_I2C_REG_BOOT_FLAG_PASS 0x50 #define MCU_I2C_REG_LED 0x89 /* khadas mcu part end */ void board_boot_order(u32 *spl_boot_list) { const void *blob = gd->fdt_blob; int chosen_node = fdt_path_offset(blob, "/chosen"); int idx = 0; int elem; int boot_device; int node; const char *conf; /* khadas mcu part begin */ uchar mcu_boot_mode; uchar mcu_boot_flag; uchar mcu_led_normal = 8; /* white breath */ uchar mcu_led_reset = 1; /* white solid */ int ret; struct udevice *bus; struct udevice *dev; ret = uclass_first_device(UCLASS_I2C, &bus); if (ret) goto mcu_skip; ret = i2c_get_chip(bus, MCU_I2C_CHIP_ADDR, 1, &dev); if (ret) goto mcu_skip; ret = dm_i2c_read(dev, MCU_I2C_REG_BOOT_MODE, &mcu_boot_mode, 1); ret = dm_i2c_read(dev, MCU_I2C_REG_BOOT_FLAG, &mcu_boot_flag, 1); printf("MCU: boot mode 0x20: %d, flag 0x92: %d\n", mcu_boot_mode, mcu_boot_flag); // reset boot flag if ( mcu_boot_flag != 0 ) { mcu_boot_flag = mcu_boot_flag > 10 ? 0 : mcu_boot_flag ^ MCU_I2C_REG_BOOT_FLAG_PASS; dm_i2c_write(dev, MCU_I2C_REG_BOOT_FLAG, &mcu_boot_flag, 1); printf("MCU: boot flag < %d\n", mcu_boot_flag); if ( mcu_boot_flag != 0 ) dm_i2c_write(dev, MCU_I2C_REG_LED, &mcu_led_reset, 1); } else { dm_i2c_write(dev, MCU_I2C_REG_LED, &mcu_led_normal, 1); } mcu_skip: /* khadas mcu part end */ if (chosen_node < 0) { debug("%s: /chosen not found, using spl_boot_device()\n", __func__); spl_boot_list[0] = spl_boot_device(); return; } printf("%s: /chosen found, using spl_boot_device()\n", __func__); for (elem = 0; (conf = fdt_stringlist_get(blob, chosen_node, "u-boot,spl-boot-order", elem, NULL)); elem++) { const char *alias; printf("!!! %s: \n", conf); /* Handle the case of 'same device the SPL was loaded from' */ if (strncmp(conf, "same-as-spl", 11) == 0) { // /mmc@fe2c0000 - SD // /mmc@fe2e0000 - EMMC mcu_boot_flag &= 0x0F; // restore original flag if (mcu_boot_flag == 1 || mcu_boot_flag == 2 || mcu_boot_flag == 5) conf = "/spi@fe2b0000/flash@1"; else if (mcu_boot_flag == 3) conf = "/mmc@fe2e0000"; else if (mcu_boot_mode == MCU_I2C_REG_BOOT_MODE_MMC) continue; else conf = board_spl_was_booted_from(); printf("+++ %s: \n", conf); if (!conf) continue; } /* First check if the list element is an alias */ alias = fdt_get_alias(blob, conf); if (alias) conf = alias; /* Try to resolve the config item (or alias) as a path */ node = fdt_path_offset(blob, conf); if (node < 0) { debug("%s: could not find %s in FDT", __func__, conf); continue; } /* Try to map this back onto SPL boot devices */ boot_device = spl_node_to_boot_device(node); if (boot_device < 0) { debug("%s: could not map node @%x to a boot-device\n", __func__, node); continue; } spl_boot_list[idx++] = boot_device; } /* If we had no matches, fall back to spl_boot_device */ if (idx == 0) spl_boot_list[0] = spl_boot_device(); } #endif