This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
products:sbc:edge2:hardware:edge2-boot-flow [2023/05/15 21:57] hyphop [U-boot spl] |
products:sbc:edge2:hardware:edge2-boot-flow [2023/05/17 07:14] hyphop [Reboot from SPI flash U-Boot via i2c command] |
||
---|---|---|---|
Line 3: | Line 3: | ||
====== Edge2 Boot flow ====== | ====== Edge2 Boot flow ====== | ||
- | Edge2 have advanced and flexible | + | [[:Edge2]] have advanced and flexible |
Line 14: | Line 14: | ||
====== Hardware buttons ====== | ====== Hardware buttons ====== | ||
- | |||
- | WIP: | ||
* '' | * '' | ||
Line 24: | Line 22: | ||
| | ||
- | ====== | + | ====== |
- | '' | + | See too: [[#mcu-registers-annotation]] |
- | ^ bootmode | + | ===== Boot mode ====== |
+ | |||
+ | Common boot mode configuration '' | ||
+ | |||
+ | ^ boot mode ^ value ^ | ||
| spi | 0 | | | spi | 0 | | ||
| mmc | 1 | | | mmc | 1 | | ||
- | ====== Reboot mode ======= | ||
- | '' | + | ```sh boot-mode read |
+ | i2cget -f -y 2 0x18 0x20 | ||
+ | ``` | ||
+ | |||
+ | ===== Boot flag ====== | ||
+ | |||
+ | This flag '' | ||
- | ^ | + | ^ |
| disabled | | disabled | ||
- | | OOWOW request |1 | | + | | [[/ |
- | | OOWOW rescue | + | | boot from SPI |2 | |
+ | | boot from eMMC |3 | | ||
- | ====== Reboot modes by MCU ======= | ||
- | '' | + | ```sh boot-flag read |
+ | i2cget | ||
+ | ``` | ||
- | ^ oowow_mode | + | <WRAP important > |
- | | spi | + | boot-flag will be used only one time and after reboot will be masked by '' |
- | | mmc | + | </ |
- | | default reboot | + | |
+ | ^ boot flag note ^ mask ^ | ||
+ | | spl mask |0x50 | | ||
+ | | oowow mask |0xA0 | | ||
+ | |||
+ | |||
+ | <WRAP important > | ||
+ | boot-flag value ''> | ||
+ | </ | ||
+ | |||
+ | ===== Reboot mode ====== | ||
+ | |||
+ | We can reboot device by non standard way via MCU '' | ||
+ | |||
+ | ^ reboot mode ^ value ^ | ||
+ | | SPI |0 | | ||
+ | | normal reboot | ||
+ | | eMMC | ||
+ | |||
+ | ```sh reboot-mode read | ||
+ | i2cset -f -y 2 0x18 0x91 value | ||
+ | ``` | ||
<WRAP important > | <WRAP important > | ||
Line 54: | Line 84: | ||
</ | </ | ||
- | + | <WRAP important > | |
+ | Only '' | ||
+ | '' | ||
+ | '' | ||
+ | </ | ||
+ | |||
+ | |||
+ | See too: [[# | ||
====== Boot modes oowow shell usage ====== | ====== Boot modes oowow shell usage ====== | ||
WIP: | WIP: | ||
- | ==== Set boot mode ==== | + | ==== Boot mode setup examples |
```shell | ```shell | ||
+ | |||
+ | ## read current boot-mode | ||
+ | |||
~# bootmode | ~# bootmode | ||
spi | spi | ||
+ | |||
+ | ## setup to MMC | ||
~# bootmode mmc | ~# bootmode mmc | ||
Line 70: | Line 112: | ||
~# bootmode | ~# bootmode | ||
mmc | mmc | ||
+ | |||
+ | ## setup to SPI | ||
~# bootmode spi | ~# bootmode spi | ||
Line 103: | Line 147: | ||
``` | ``` | ||
- | ==== Reboot by MCU ==== | + | ==== Reboot by MCU examples |
Forced hardware reboot | Forced hardware reboot | ||
```shell | ```shell | ||
+ | ## oowow shell | ||
~# mcu_reboot | ~# mcu_reboot | ||
- | ~# i2cset -f -y 2 0x18 0x91 2 | + | ## common system |
+ | ~# i2cset -f -y 2 0x18 0x91 1 | ||
``` | ``` | ||
Line 122: | Line 168: | ||
==== Reboot from SPI flash U-Boot via i2c command ==== | ==== Reboot from SPI flash U-Boot via i2c command ==== | ||
- | WIP: not works as need | + | ```sh reset and use u-boot from spi flash |
- | + | ||
- | ```sh reboot into oowow | + | |
- | i2cset | + | |
i2cset -f -y 2 0x18 0x91 0 | i2cset -f -y 2 0x18 0x91 0 | ||
``` | ``` | ||
+ | |||
+ | <WRAP important > | ||
+ | In this case U-boot will be started from SPI flash, next booting will in same u-boot prio '' | ||
+ | </ | ||
====== SPL stage ====== | ====== SPL stage ====== | ||
Line 166: | Line 213: | ||
MCU version: 02 & 03 | MCU version: 02 & 03 | ||
- | 0x91 BOOT_MODE | + | 0x91 REBOOT_MODE |
0 - reset and boot from SPI | 0 - reset and boot from SPI | ||
+ | 1 - reset normal | ||
2 - reset and boot from eMMC | 2 - reset and boot from eMMC | ||
- | 1 - reset | ||
0x92 BOOT_FLAG | 0x92 BOOT_FLAG | ||
Line 178: | Line 225: | ||
``` | ``` | ||
| | ||
+ | See too: [[# | ||
+ | |||
===== U-boot spl ===== | ===== U-boot spl ===== | ||
Line 183: | Line 232: | ||
```c u-boot/ | ```c u-boot/ | ||
+ | |||
+ | // ...... | ||
+ | |||
+ | /* khadas mcu part begin */ | ||
+ | #define MCU_I2C_BUS_NUM | ||
+ | #define MCU_I2C_CHIP_ADDR | ||
+ | #define MCU_I2C_REG_BOOT_MODE | ||
+ | #define MCU_I2C_REG_BOOT_MODE_SPI | ||
+ | #define MCU_I2C_REG_BOOT_MODE_MMC | ||
+ | #define MCU_I2C_REG_BOOT_FLAG | ||
+ | #define MCU_I2C_REG_RESET_MODE | ||
+ | #define MCU_I2C_REG_BOOT_FLAG_NORMAL 0x00 | ||
+ | #define MCU_I2C_REG_BOOT_FLAG_FUNC | ||
+ | #define MCU_I2C_REG_BOOT_FLAG_OOWOW | ||
+ | #define MCU_I2C_REG_BOOT_FLAG_SPI | ||
+ | #define MCU_I2C_REG_BOOT_FLAG_EMMC | ||
+ | #define MCU_I2C_REG_BOOT_FLAG_RESCUE 0x05 | ||
+ | #define MCU_I2C_REG_BOOT_FLAG_PASS | ||
+ | |||
+ | #define MCU_I2C_REG_LED | ||
+ | /* khadas mcu part end */ | ||
+ | |||
+ | void board_boot_order(u32 *spl_boot_list) | ||
+ | { | ||
+ | const void *blob = gd-> | ||
+ | int chosen_node = fdt_path_offset(blob, | ||
+ | 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 | ||
+ | int ret; | ||
+ | struct udevice *bus; | ||
+ | struct udevice *dev; | ||
+ | |||
+ | ret = uclass_first_device(UCLASS_I2C, | ||
+ | if (ret) goto mcu_skip; | ||
+ | ret = i2c_get_chip(bus, | ||
+ | if (ret) goto mcu_skip; | ||
+ | ret = dm_i2c_read(dev, | ||
+ | ret = dm_i2c_read(dev, | ||
+ | printf(" | ||
+ | mcu_boot_mode, | ||
+ | // 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, | ||
+ | printf(" | ||
+ | if ( mcu_boot_flag != 0 ) | ||
+ | dm_i2c_write(dev, | ||
+ | } else { | ||
+ | dm_i2c_write(dev, | ||
+ | } | ||
+ | mcu_skip: | ||
+ | /* khadas mcu part end */ | ||
+ | |||
+ | if (chosen_node < 0) { | ||
+ | debug(" | ||
+ | __func__); | ||
+ | spl_boot_list[0] = spl_boot_device(); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | printf(" | ||
+ | |||
+ | for (elem = 0; | ||
+ | (conf = fdt_stringlist_get(blob, | ||
+ | " | ||
+ | | ||
+ | const char *alias; | ||
+ | |||
+ | printf(" | ||
+ | |||
+ | /* Handle the case of 'same device the SPL was loaded from' */ | ||
+ | if (strncmp(conf, | ||
+ | |||
+ | // / | ||
+ | // / | ||
+ | |||
+ | mcu_boot_flag &= 0x0F; // restore original flag | ||
+ | if (mcu_boot_flag == 1 || mcu_boot_flag == 2 || mcu_boot_flag == 5) | ||
+ | conf = "/ | ||
+ | else if (mcu_boot_flag == 3) | ||
+ | conf = "/ | ||
+ | else if (mcu_boot_mode == MCU_I2C_REG_BOOT_MODE_MMC) | ||
+ | continue; | ||
+ | else | ||
+ | conf = board_spl_was_booted_from(); | ||
+ | |||
+ | printf(" | ||
+ | if (!conf) | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | /* First check if the list element is an alias */ | ||
+ | alias = fdt_get_alias(blob, | ||
+ | if (alias) | ||
+ | conf = alias; | ||
+ | |||
+ | /* Try to resolve the config item (or alias) as a path */ | ||
+ | node = fdt_path_offset(blob, | ||
+ | if (node < 0) { | ||
+ | debug(" | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | /* Try to map this back onto SPL boot devices */ | ||
+ | boot_device = spl_node_to_boot_device(node); | ||
+ | if (boot_device < 0) { | ||
+ | debug(" | ||
+ | __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 | ||
+ | |||
``` | ``` | ||