diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/README.drivers.eth | 215 | ||||
-rw-r--r-- | doc/api/efi.rst | 9 | ||||
-rw-r--r-- | doc/board/google/chromebook_coral.rst | 2 | ||||
-rw-r--r-- | doc/board/index.rst | 2 | ||||
-rw-r--r-- | doc/board/st/index.rst | 9 | ||||
-rw-r--r-- | doc/board/st/stm32mp1.rst | 611 | ||||
-rw-r--r-- | doc/board/toradex/apalix-imx8.rst | 82 | ||||
-rw-r--r-- | doc/board/toradex/colibri-imx8x.rst | 82 | ||||
-rw-r--r-- | doc/board/toradex/colibri_imx7.rst | 127 | ||||
-rw-r--r-- | doc/board/toradex/index.rst | 12 | ||||
-rw-r--r-- | doc/board/toradex/verdin-imx8mm.rst | 112 | ||||
-rw-r--r-- | doc/device-tree-bindings/gpio/intel,apl-gpio.txt | 2 | ||||
-rw-r--r-- | doc/device-tree-bindings/i2c/i2c-gpio.txt | 4 | ||||
-rw-r--r-- | doc/device-tree-bindings/misc/bootcounter.txt | 21 | ||||
-rw-r--r-- | doc/device-tree-bindings/net/ti,dp83867.txt | 35 | ||||
-rw-r--r-- | doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt | 2 | ||||
-rw-r--r-- | doc/driver-model/ethernet.rst | 321 | ||||
-rw-r--r-- | doc/driver-model/index.rst | 1 | ||||
-rw-r--r-- | doc/uefi/uefi.rst | 12 |
19 files changed, 1408 insertions, 253 deletions
diff --git a/doc/README.drivers.eth b/doc/README.drivers.eth deleted file mode 100644 index 1a9a23b51b..0000000000 --- a/doc/README.drivers.eth +++ /dev/null @@ -1,215 +0,0 @@ -!!! WARNING !!! - -This guide describes to the old way of doing things. No new Ethernet drivers -should be implemented this way. All new drivers should be written against the -U-Boot core driver model. See doc/driver-model/README.txt - ------------------------ - Ethernet Driver Guide ------------------------ - -The networking stack in Das U-Boot is designed for multiple network devices -to be easily added and controlled at runtime. This guide is meant for people -who wish to review the net driver stack with an eye towards implementing your -own ethernet device driver. Here we will describe a new pseudo 'APE' driver. - ------------------- - Driver Functions ------------------- - -All functions you will be implementing in this document have the return value -meaning of 0 for success and non-zero for failure. - - ---------- - Register - ---------- - -When U-Boot initializes, it will call the common function eth_initialize(). -This will in turn call the board-specific board_eth_init() (or if that fails, -the cpu-specific cpu_eth_init()). These board-specific functions can do random -system handling, but ultimately they will call the driver-specific register -function which in turn takes care of initializing that particular instance. - -Keep in mind that you should code the driver to avoid storing state in global -data as someone might want to hook up two of the same devices to one board. -Any such information that is specific to an interface should be stored in a -private, driver-defined data structure and pointed to by eth->priv (see below). - -So the call graph at this stage would look something like: -board_init() - eth_initialize() - board_eth_init() / cpu_eth_init() - driver_register() - initialize eth_device - eth_register() - -At this point in time, the only thing you need to worry about is the driver's -register function. The pseudo code would look something like: -int ape_register(bd_t *bis, int iobase) -{ - struct ape_priv *priv; - struct eth_device *dev; - struct mii_dev *bus; - - priv = malloc(sizeof(*priv)); - if (priv == NULL) - return -ENOMEM; - - dev = malloc(sizeof(*dev)); - if (dev == NULL) { - free(priv); - return -ENOMEM; - } - - /* setup whatever private state you need */ - - memset(dev, 0, sizeof(*dev)); - sprintf(dev->name, "APE"); - - /* - * if your device has dedicated hardware storage for the - * MAC, read it and initialize dev->enetaddr with it - */ - ape_mac_read(dev->enetaddr); - - dev->iobase = iobase; - dev->priv = priv; - dev->init = ape_init; - dev->halt = ape_halt; - dev->send = ape_send; - dev->recv = ape_recv; - dev->write_hwaddr = ape_write_hwaddr; - - eth_register(dev); - -#ifdef CONFIG_PHYLIB - bus = mdio_alloc(); - if (!bus) { - free(priv); - free(dev); - return -ENOMEM; - } - - bus->read = ape_mii_read; - bus->write = ape_mii_write; - mdio_register(bus); -#endif - - return 1; -} - -The exact arguments needed to initialize your device are up to you. If you -need to pass more/less arguments, that's fine. You should also add the -prototype for your new register function to include/netdev.h. - -The return value for this function should be as follows: -< 0 - failure (hardware failure, not probe failure) ->=0 - number of interfaces detected - -You might notice that many drivers seem to use xxx_initialize() rather than -xxx_register(). This is the old naming convention and should be avoided as it -causes confusion with the driver-specific init function. - -Other than locating the MAC address in dedicated hardware storage, you should -not touch the hardware in anyway. That step is handled in the driver-specific -init function. Remember that we are only registering the device here, we are -not checking its state or doing random probing. - - ----------- - Callbacks - ----------- - -Now that we've registered with the ethernet layer, we can start getting some -real work done. You will need five functions: - int ape_init(struct eth_device *dev, bd_t *bis); - int ape_send(struct eth_device *dev, volatile void *packet, int length); - int ape_recv(struct eth_device *dev); - int ape_halt(struct eth_device *dev); - int ape_write_hwaddr(struct eth_device *dev); - -The init function checks the hardware (probing/identifying) and gets it ready -for send/recv operations. You often do things here such as resetting the MAC -and/or PHY, and waiting for the link to autonegotiate. You should also take -the opportunity to program the device's MAC address with the dev->enetaddr -member. This allows the rest of U-Boot to dynamically change the MAC address -and have the new settings be respected. - -The send function does what you think -- transmit the specified packet whose -size is specified by length (in bytes). You should not return until the -transmission is complete, and you should leave the state such that the send -function can be called multiple times in a row. - -The recv function should process packets as long as the hardware has them -readily available before returning. i.e. you should drain the hardware fifo. -For each packet you receive, you should call the net_process_received_packet() function on it -along with the packet length. The common code sets up packet buffers for you -already in the .bss (net_rx_packets), so there should be no need to allocate your -own. This doesn't mean you must use the net_rx_packets array however; you're -free to call the net_process_received_packet() function with any buffer you wish. So the pseudo -code here would look something like: -int ape_recv(struct eth_device *dev) -{ - int length, i = 0; - ... - while (packets_are_available()) { - ... - length = ape_get_packet(&net_rx_packets[i]); - ... - net_process_received_packet(&net_rx_packets[i], length); - ... - if (++i >= PKTBUFSRX) - i = 0; - ... - } - ... - return 0; -} - -The halt function should turn off / disable the hardware and place it back in -its reset state. It can be called at any time (before any call to the related -init function), so make sure it can handle this sort of thing. - -The write_hwaddr function should program the MAC address stored in dev->enetaddr -into the Ethernet controller. - -So the call graph at this stage would look something like: -some net operation (ping / tftp / whatever...) - eth_init() - dev->init() - eth_send() - dev->send() - eth_rx() - dev->recv() - eth_halt() - dev->halt() - --------------------------------- - CONFIG_PHYLIB / CONFIG_CMD_MII --------------------------------- - -If your device supports banging arbitrary values on the MII bus (pretty much -every device does), you should add support for the mii command. Doing so is -fairly trivial and makes debugging mii issues a lot easier at runtime. - -After you have called eth_register() in your driver's register function, add -a call to mdio_alloc() and mdio_register() like so: - bus = mdio_alloc(); - if (!bus) { - free(priv); - free(dev); - return -ENOMEM; - } - - bus->read = ape_mii_read; - bus->write = ape_mii_write; - mdio_register(bus); - -And then define the mii_read and mii_write functions if you haven't already. -Their syntax is straightforward: - int mii_read(struct mii_dev *bus, int addr, int devad, int reg); - int mii_write(struct mii_dev *bus, int addr, int devad, int reg, - u16 val); - -The read function should read the register 'reg' from the phy at address 'addr' -and return the result to its caller. The implementation for the write function -should logically follow. diff --git a/doc/api/efi.rst b/doc/api/efi.rst index bc59382608..631c0ceb1d 100644 --- a/doc/api/efi.rst +++ b/doc/api/efi.rst @@ -125,6 +125,15 @@ Graphical output protocol .. kernel-doc:: lib/efi_loader/efi_gop.c :internal: +Load file 2 protocol +~~~~~~~~~~~~~~~~~~~~ + +The load file 2 protocol can be used by the Linux kernel to load the initial +RAM disk. U-Boot can be configured to provide an implementation. + +.. kernel-doc:: lib/efi_loader/efi_load_initrd.c + :internal: + Network protocols ~~~~~~~~~~~~~~~~~ diff --git a/doc/board/google/chromebook_coral.rst b/doc/board/google/chromebook_coral.rst index d10e0c4954..40bd9397d4 100644 --- a/doc/board/google/chromebook_coral.rst +++ b/doc/board/google/chromebook_coral.rst @@ -179,7 +179,7 @@ Partial memory map ffffffff Top of ROM (and last byte of 32-bit address space) ffff8000 TPL loaded here (from IFWI) ff000000 Bottom of ROM - fefc000 Top of CAR region + fefc0000 Top of CAR region fef96000 Stack for FSP-M fef40000 59000 FSP-M fef11000 SPL loaded here diff --git a/doc/board/index.rst b/doc/board/index.rst index b8b956d730..51a2ae6f28 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -16,4 +16,6 @@ Board-specific doc renesas/index rockchip/index sifive/index + st/index + toradex/index xilinx/index diff --git a/doc/board/st/index.rst b/doc/board/st/index.rst new file mode 100644 index 0000000000..91f1d51b42 --- /dev/null +++ b/doc/board/st/index.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +STMicroelectronics +================== + +.. toctree:: + :maxdepth: 2 + + stm32mp1 diff --git a/doc/board/st/stm32mp1.rst b/doc/board/st/stm32mp1.rst new file mode 100644 index 0000000000..1640bf910e --- /dev/null +++ b/doc/board/st/stm32mp1.rst @@ -0,0 +1,611 @@ +.. SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause +.. sectionauthor:: Patrick Delaunay <patrick.delaunay@st.com> + +STM32MP15x boards +================= + +This is a quick instruction for setup STM32MP15x boards. + +Supported devices +----------------- + +U-Boot supports STMP32MP15x SoCs: + + - STM32MP157 + - STM32MP153 + - STM32MP151 + +The STM32MP15x is a Cortex-A MPU aimed at various applications. + +It features: + + - Dual core Cortex-A7 application core (Single on STM32MP151) + - 2D/3D image composition with GPU (only on STM32MP157) + - Standard memories interface support + - Standard connectivity, widely inherited from the STM32 MCU family + - Comprehensive security support + +Everything is supported in Linux but U-Boot is limited to: + + 1. UART + 2. SD card/MMC controller (SDMMC) + 3. NAND controller (FMC) + 4. NOR controller (QSPI) + 5. USB controller (OTG DWC2) + 6. Ethernet controller + +And the necessary drivers + + 1. I2C + 2. STPMIC1 (PMIC and regulator) + 3. Clock, Reset, Sysreset + 4. Fuse + +Currently the following boards are supported: + + + stm32mp157a-avenger96.dts + + stm32mp157a-dk1.dts + + stm32mp157c-dk2.dts + + stm32mp157c-ed1.dts + + stm32mp157c-ev1.dts + +Boot Sequences +-------------- + +3 boot configurations are supported with: + ++----------+------------------------+-------------------------+--------------+ +| **ROM** | **FSBL** | **SSBL** | **OS** | ++ **code** +------------------------+-------------------------+--------------+ +| | First Stage Bootloader | Second Stage Bootloader | Linux Kernel | ++ +------------------------+-------------------------+--------------+ +| | embedded RAM | DDR | ++----------+------------------------+-------------------------+--------------+ + +The **Trusted** boot chain +`````````````````````````` + +defconfig_file : stm32mp15_trusted_defconfig + + +-------------+-------------------------+------------+-------+ + | ROM code | FSBL | SSBL | OS | + + +-------------------------+------------+-------+ + | |Trusted Firmware-A (TF-A)| U-Boot | Linux | + +-------------+-------------------------+------------+-------+ + | TrustZone |TF-A secure monitor | + +-------------+-------------------------+------------+-------+ + +TF-A performs a full initialization of Secure peripherals and installs a +secure monitor (BL32=SPMin). + +U-Boot is running in normal world and uses TF-A monitor to access +to secure resources. + +The **Trusted** boot chain with **OP-TEE** +`````````````````````````````````````````` + +defconfig_file : stm32mp15_optee_defconfig + + +-------------+-------------------------+------------+-------+ + | ROM code | FSBL | SSBL | OS | + + +-------------------------+------------+-------+ + | |Trusted Firmware-A (TF-A)| U-Boot | Linux | + +-------------+-------------------------+------------+-------+ + | TrustZone |OP-TEE | + +-------------+-------------------------+------------+-------+ + +TF-A performs a full initialization of Secure peripherals and installs OP-TEE +from specific partitions (teeh, teed, teex). + +U-Boot is running in normal world and uses OP-TEE monitor to access +to secure resources. + +The **Basic** boot chain +```````````````````````` + +defconfig_file : stm32mp15_basic_defconfig + + +-------------+------------+------------+-------+ + | ROM code | FSBL | SSBL | OS | + + +------------+------------+-------+ + | |U-Boot SPL | U-Boot | Linux | + +-------------+------------+------------+-------+ + | TrustZone | | PSCI from U-Boot | + +-------------+------------+------------+-------+ + +SPL has limited security initialization + +U-Boot is running in secure mode and provide a secure monitor to the kernel +with only PSCI support (Power State Coordination Interface defined by ARM). + +All the STM32MP15x boards supported by U-Boot use the same generic board +stm32mp1 which support all the bootable devices. + +Each board is configured only with the associated device tree. + +Device Tree Selection +--------------------- + +You need to select the appropriate device tree for your board, +the supported device trees for STM32MP15x are: + ++ ev1: eval board with pmic stpmic1 (ev1 = mother board + daughter ed1) + + + stm32mp157c-ev1 + ++ ed1: daughter board with pmic stpmic1 + + + stm32mp157c-ed1 + ++ dk1: Discovery board + + + stm32mp157a-dk1 + ++ dk2: Discovery board = dk1 with a BT/WiFI combo and a DSI panel + + + stm32mp157c-dk2 + ++ avenger96: Avenger96 board from Arrow Electronics + + + stm32mp157a-avenger96 + +Build Procedure +--------------- + +1. Install the required tools for U-Boot + + * install package needed in U-Boot makefile + (libssl-dev, swig, libpython-dev...) + + * install ARMv7 toolchain for 32bit Cortex-A (from Linaro, + from SDK for STM32MP15x, or any crosstoolchains from your distribution) + (you can use any gcc cross compiler compatible with U-Boot) + +2. Set the cross compiler:: + + # export CROSS_COMPILE=/path/to/toolchain/arm-linux-gnueabi- + +3. Select the output directory (optional):: + + # export KBUILD_OUTPUT=/path/to/output + + for example: use one output directory for each configuration:: + + # export KBUILD_OUTPUT=stm32mp15_trusted + # export KBUILD_OUTPUT=stm32mp15_optee + # export KBUILD_OUTPUT=stm32mp15_basic + + you can build outside of code directory:: + + # export KBUILD_OUTPUT=../build/stm32mp15_trusted + +4. Configure U-Boot:: + + # make <defconfig_file> + + with <defconfig_file>: + + - For **trusted** boot mode : **stm32mp15_trusted_defconfig** + - For **trusted** with OP-TEE boot mode : **stm32mp15_optee_defconfig** + - For basic boot mode: stm32mp15_basic_defconfig + +5. Configure the device-tree and build the U-Boot image:: + + # make DEVICE_TREE=<name> all + + Examples: + + a) trusted boot on ev1:: + + # export KBUILD_OUTPUT=stm32mp15_trusted + # make stm32mp15_trusted_defconfig + # make DEVICE_TREE=stm32mp157c-ev1 all + + b) trusted with OP-TEE boot on dk2:: + + # export KBUILD_OUTPUT=stm32mp15_optee + # make stm32mp15_optee_defconfig + # make DEVICE_TREE=stm32mp157c-dk2 all + + c) basic boot on ev1:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157c-ev1 all + + d) basic boot on ed1:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157c-ed1 all + + e) basic boot on dk1:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157a-dk1 all + + f) basic boot on avenger96:: + + # export KBUILD_OUTPUT=stm32mp15_basic + # make stm32mp15_basic_defconfig + # make DEVICE_TREE=stm32mp157a-avenger96 all + +6. Output files + + BootRom and TF-A expect binaries with STM32 image header + SPL expects file with U-Boot uImage header + + So in the output directory (selected by KBUILD_OUTPUT), + you can found the needed files: + + - For **Trusted** boot (with or without OP-TEE) + + - FSBL = **tf-a.stm32** (provided by TF-A compilation) + - SSBL = **u-boot.stm32** + + - For Basic boot + + - FSBL = spl/u-boot-spl.stm32 + - SSBL = u-boot.img + +Switch Setting for Boot Mode +---------------------------- + +You can select the boot mode, on the board with one switch, to select +the boot pin values = BOOT0, BOOT1, BOOT2 + + +-------------+---------+---------+---------+ + |*Boot Mode* | *BOOT2* | *BOOT1* | *BOOT0* | + +=============+=========+=========+=========+ + | Recovery | 0 | 0 | 0 | + +-------------+---------+---------+---------+ + | NOR | 0 | 0 | 1 | + +-------------+---------+---------+---------+ + | eMMC | 0 | 1 | 0 | + +-------------+---------+---------+---------+ + | NAND | 0 | 1 | 1 | + +-------------+---------+---------+---------+ + | Reserved | 1 | 0 | 0 | + +-------------+---------+---------+---------+ + | SD-Card | 1 | 0 | 1 | + +-------------+---------+---------+---------+ + | Recovery | 1 | 1 | 0 | + +-------------+---------+---------+---------+ + | SPI-NAND | 1 | 1 | 1 | + +-------------+---------+---------+---------+ + +- on the **daugther board ed1 = MB1263** with the switch SW1 +- on **Avenger96** with switch S3 (NOR and SPI-NAND are not applicable) +- on board **DK1/DK2** with the switch SW1 = BOOT0, BOOT2 + with only 2 pins available (BOOT1 is forced to 0 and NOR not supported), + the possible value becomes: + + +-------------+---------+---------+ + |*Boot Mode* | *BOOT2* | *BOOT0* | + +=============+=========+=========+ + | Recovery | 0 | 0 | + +-------------+---------+---------+ + | NOR (NA)| 0 | 1 | + +-------------+---------+---------+ + | Reserved | 1 | 0 | + +-------------+---------+---------+ + | SD-Card | 1 | 1 | + +-------------+---------+---------+ + +Recovery is a boot from serial link (UART/USB) and it is used with +STM32CubeProgrammer tool to load executable in RAM and to update the flash +devices available on the board (NOR/NAND/eMMC/SD card). + +The communication between HOST and board is based on + + - for UARTs : the uart protocol used with all MCU STM32 + - for USB : based on USB DFU 1.1 (without the ST extensions used on MCU STM32) + +Prepare an SD card +------------------ + +The minimal requirements for STMP32MP15x boot up to U-Boot are: + +- GPT partitioning (with gdisk or with sgdisk) +- 2 fsbl partitions, named fsbl1 and fsbl2, size at least 256KiB +- one ssbl partition for U-Boot + +Then the minimal GPT partition is: + + +-------+--------+---------+-------------+ + | *Num* | *Name* | *Size* | *Content* | + +=======+========+=========+=============+ + | 1 | fsbl1 | 256 KiB | TF-A or SPL | + +-------+--------+---------+-------------+ + | 2 | fsbl2 | 256 KiB | TF-A or SPL | + +-------+--------+---------+-------------+ + | 3 | ssbl | enought | U-Boot | + +-------+--------+---------+-------------+ + | 4 | <any> | <any> | Rootfs | + +-------+--------+---------+-------------+ + +Add a 4th partition (Rootfs) marked bootable with a file extlinux.conf +following the Generic Distribution feature (doc/README.distro for use). + +According the used card reader select the correct block device +(for example /dev/sdx or /dev/mmcblk0). + +In the next example, it is /dev/mmcblk0 + +For example: with gpt table with 128 entries + +a) remove previous formatting:: + + # sgdisk -o /dev/<SD card dev> + +b) create minimal image:: + + # sgdisk --resize-table=128 -a 1 \ + -n 1:34:545 -c 1:fsbl1 \ + -n 2:546:1057 -c 2:fsbl2 \ + -n 3:1058:5153 -c 3:ssbl \ + -n 4:5154: -c 4:rootfs \ + -p /dev/<SD card dev> + + With other partition for kernel one partition rootfs for kernel. + +c) copy the FSBL (2 times) and SSBL file on the correct partition. + in this example in partition 1 to 3 + + for basic boot mode : <SD card dev> = /dev/mmcblk0:: + + # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p1 + # dd if=u-boot-spl.stm32 of=/dev/mmcblk0p2 + # dd if=u-boot.img of=/dev/mmcblk0p3 + + for trusted boot mode: :: + + # dd if=tf-a.stm32 of=/dev/mmcblk0p1 + # dd if=tf-a.stm32 of=/dev/mmcblk0p2 + # dd if=u-boot.stm32 of=/dev/mmcblk0p3 + +To boot from SD card, select BootPinMode = 1 0 1 and reset. + +Prepare eMMC +------------ + +You can use U-Boot to copy binary in eMMC. + +In the next example, you need to boot from SD card and the images +(u-boot-spl.stm32, u-boot.img) are presents on SD card (mmc 0) +in ext4 partition 4 (bootfs). + +To boot from SD card, select BootPinMode = 1 0 1 and reset. + +Then you update the eMMC with the next U-Boot command : + +a) prepare GPT on eMMC, + example with 2 partitions, bootfs and roots:: + + # setenv emmc_part "name=ssbl,size=2MiB;name=bootfs,type=linux,bootable,size=64MiB;name=rootfs,type=linux,size=512" + # gpt write mmc 1 ${emmc_part} + +b) copy SPL on eMMC on firts boot partition + (SPL max size is 256kB, with LBA 512, 0x200):: + + # ext4load mmc 0:4 0xC0000000 u-boot-spl.stm32 + # mmc dev 1 + # mmc partconf 1 1 1 1 + # mmc write ${fileaddr} 0 200 + # mmc partconf 1 1 1 0 + +c) copy U-Boot in first GPT partition of eMMC:: + + # ext4load mmc 0:4 0xC0000000 u-boo t.img + # mmc dev 1 + # part start mmc 1 1 partstart + # mmc write ${fileaddr} ${partstart} ${filesize} + +To boot from eMMC, select BootPinMode = 0 1 0 and reset. + +MAC Address +----------- + +Please read doc/README.enetaddr for the implementation guidelines for mac id +usage. Basically, environment has precedence over board specific storage. + +For STMicroelectonics board, it is retrieved in STM32MP15x OTP : + + - OTP_57[31:0] = MAC_ADDR[31:0] + - OTP_58[15:0] = MAC_ADDR[47:32] + +To program a MAC address on virgin OTP words above, you can use the fuse command +on bank 0 to access to internal OTP: + +Prerequisite: check if a MAC address isn't yet programmed in OTP + +1) check OTP: their value must be equal to 0 + + STM32MP> fuse sense 0 57 2 + Sensing bank 0: + Word 0x00000039: 00000000 00000000 + +2) check environment variable + + STM32MP> env print ethaddr + ## Error: "ethaddr" not defined + +Example to set mac address "12:34:56:78:9a:bc" + +1) Write OTP:: + + STM32MP> fuse prog -y 0 57 0x78563412 0x0000bc9a + +2) Read OTP:: + + STM32MP> fuse sense 0 57 2 + Sensing bank 0: + Word 0x00000039: 78563412 0000bc9a + +3) next REBOOT, in the trace:: + + ### Setting environment from OTP MAC address = "12:34:56:78:9a:bc" + +4) check env update:: + + STM32MP> env print ethaddr + ethaddr=12:34:56:78:9a:bc + +.. warning:: This command can't be executed twice on the same board as + OTP are protected. It is already done for the board + provided by STMicroelectronics. + +Coprocessor firmware +-------------------- + +U-Boot can boot the coprocessor before the kernel (coprocessor early boot). + +a) Manuallly by using rproc commands (update the bootcmd) + + Configurations:: + + # env set name_copro "rproc-m4-fw.elf" + # env set dev_copro 0 + # env set loadaddr_copro 0xC1000000 + + Load binary from bootfs partition (number 4) on SD card (mmc 0):: + + # ext4load mmc 0:4 ${loadaddr_copro} ${name_copro} + + => ${filesize} variable is updated with the size of the loaded file. + + Start M4 firmware with remote proc command:: + + # rproc init + # rproc load ${dev_copro} ${loadaddr_copro} ${filesize} + # rproc start ${dev_copro}"00270033 + +b) Automatically by using FIT feature and generic DISTRO bootcmd + + see examples in the board stm32mp1 directory: fit_copro_kernel_dtb.its + + Generate FIT including kernel + device tree + M4 firmware with cfg with M4 boot:: + + $> mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb + + Then using DISTRO configuration file: see extlinux.conf to select the correct + configuration: + + - stm32mp157c-ev1-m4 + - stm32mp157c-dk2-m4 + +DFU support +----------- + +The DFU is supported on ST board. + +The env variable dfu_alt_info is automatically build, and all +the memory present on the ST boards are exported. + +The dfu mode is started by the command:: + + STM32MP> dfu 0 + +On EV1 board, booting from SD card, without OP-TEE:: + + STM32MP> dfu 0 list + DFU alt settings list: + dev: RAM alt: 0 name: uImage layout: RAM_ADDR + dev: RAM alt: 1 name: devicetree.dtb layout: RAM_ADDR + dev: RAM alt: 2 name: uramdisk.image.gz layout: RAM_ADDR + dev: eMMC alt: 3 name: sdcard_fsbl1 layout: RAW_ADDR + dev: eMMC alt: 4 name: sdcard_fsbl2 layout: RAW_ADDR + dev: eMMC alt: 5 name: sdcard_ssbl layout: RAW_ADDR + dev: eMMC alt: 6 name: sdcard_bootfs layout: RAW_ADDR + dev: eMMC alt: 7 name: sdcard_vendorfs layout: RAW_ADDR + dev: eMMC alt: 8 name: sdcard_rootfs layout: RAW_ADDR + dev: eMMC alt: 9 name: sdcard_userfs layout: RAW_ADDR + dev: eMMC alt: 10 name: emmc_fsbl1 layout: RAW_ADDR + dev: eMMC alt: 11 name: emmc_fsbl2 layout: RAW_ADDR + dev: eMMC alt: 12 name: emmc_ssbl layout: RAW_ADDR + dev: eMMC alt: 13 name: emmc_bootfs layout: RAW_ADDR + dev: eMMC alt: 14 name: emmc_vendorfs layout: RAW_ADDR + dev: eMMC alt: 15 name: emmc_rootfs layout: RAW_ADDR + dev: eMMC alt: 16 name: emmc_userfs layout: RAW_ADDR + dev: MTD alt: 17 name: nor_fsbl1 layout: RAW_ADDR + dev: MTD alt: 18 name: nor_fsbl2 layout: RAW_ADDR + dev: MTD alt: 19 name: nor_ssbl layout: RAW_ADDR + dev: MTD alt: 20 name: nor_env layout: RAW_ADDR + dev: MTD alt: 21 name: nand_fsbl layout: RAW_ADDR + dev: MTD alt: 22 name: nand_ssbl1 layout: RAW_ADDR + dev: MTD alt: 23 name: nand_ssbl2 layout: RAW_ADDR + dev: MTD alt: 24 name: nand_UBI layout: RAW_ADDR + dev: VIRT alt: 25 name: OTP layout: RAW_ADDR + dev: VIRT alt: 26 name: PMIC layout: RAW_ADDR + +All the supported device are exported for dfu-util tool:: + + $> dfu-util -l + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=26, name="PMIC", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=25, name="OTP", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=24, name="nand_UBI", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=23, name="nand_ssbl2", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=22, name="nand_ssbl1", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=21, name="nand_fsbl", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=20, name="nor_env", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=19, name="nor_ssbl", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=18, name="nor_fsbl2", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=17, name="nor_fsbl1", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=16, name="emmc_userfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=15, name="emmc_rootfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=14, name="emmc_vendorfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=13, name="emmc_bootfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=12, name="emmc_ssbl", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=11, name="emmc_fsbl2", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=10, name="emmc_fsbl1", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=9, name="sdcard_userfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=8, name="sdcard_rootfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=7, name="sdcard_vendorfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=6, name="sdcard_bootfs", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=5, name="sdcard_ssbl", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=4, name="sdcard_fsbl2", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=3, name="sdcard_fsbl1", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=2, name="uramdisk.image.gz", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=1, name="devicetree.dtb", serial="002700333338511934383330" + Found DFU: [0483:5720] ver=9999, devnum=99, cfg=1, intf=0, alt=0, name="uImage", serial="002700333338511934383330" + +You can update the boot device: + +- SD card (mmc0) :: + + $> dfu-util -d 0483:5720 -a 3 -D tf-a-stm32mp157c-ev1-trusted.stm32 + $> dfu-util -d 0483:5720 -a 4 -D tf-a-stm32mp157c-ev1-trusted.stm32 + $> dfu-util -d 0483:5720 -a 5 -D u-boot-stm32mp157c-ev1-trusted.img + $> dfu-util -d 0483:5720 -a 6 -D st-image-bootfs-openstlinux-weston-stm32mp1.ext4 + $> dfu-util -d 0483:5720 -a 7 -D st-image-vendorfs-openstlinux-weston-stm32mp1.ext4 + $> dfu-util -d 0483:5720 -a 8 -D st-image-weston-openstlinux-weston-stm32mp1.ext4 + $> dfu-util -d 0483:5720 -a 9 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4 + +- EMMC (mmc1):: + + $> dfu-util -d 0483:5720 -a 10 -D tf-a-stm32mp157c-ev1-trusted.stm32 + $> dfu-util -d 0483:5720 -a 11 -D tf-a-stm32mp157c-ev1-trusted.stm32 + $> dfu-util -d 0483:5720 -a 12 -D u-boot-stm32mp157c-ev1-trusted.img + $> dfu-util -d 0483:5720 -a 13 -D st-image-bootfs-openstlinux-weston-stm32mp1.ext4 + $> dfu-util -d 0483:5720 -a 14 -D st-image-vendorfs-openstlinux-weston-stm32mp1.ext4 + $> dfu-util -d 0483:5720 -a 15 -D st-image-weston-openstlinux-weston-stm32mp1.ext4 + $> dfu-util -d 0483:5720 -a 16 -D st-image-userfs-openstlinux-weston-stm32mp1.ext4 + +- NOR:: + + $> dfu-util -d 0483:5720 -a 17 -D tf-a-stm32mp157c-ev1-trusted.stm32 + $> dfu-util -d 0483:5720 -a 18 -D tf-a-stm32mp157c-ev1-trusted.stm32 + $> dfu-util -d 0483:5720 -a 19 -D u-boot-stm32mp157c-ev1-trusted.img + +- NAND (UBI partition used for NAND only boot or NOR + NAND boot):: + + $> dfu-util -d 0483:5720 -a 21 -D tf-a-stm32mp157c-ev1-trusted.stm32 + $> dfu-util -d 0483:5720 -a 22 -D u-boot-stm32mp157c-ev1-trusted.img + $> dfu-util -d 0483:5720 -a 23 -D u-boot-stm32mp157c-ev1-trusted.img + $> dfu-util -d 0483:5720 -a 24 -D st-image-weston-openstlinux-weston-stm32mp1_nand_4_256_multivolume.ubi + +- you can also dump the OTP and the PMIC NVM with:: + + $> dfu-util -d 0483:5720 -a 25 -U otp.bin + $> dfu-util -d 0483:5720 -a 26 -U pmic.bin diff --git a/doc/board/toradex/apalix-imx8.rst b/doc/board/toradex/apalix-imx8.rst new file mode 100644 index 0000000000..4b7ea65d31 --- /dev/null +++ b/doc/board/toradex/apalix-imx8.rst @@ -0,0 +1,82 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Apalis iMX8QM V1.0B Module +========================== + +Quick Start +----------- + +- Build the ARM trusted firmware binary +- Get scfw_tcm.bin and ahab-container.img +- Build U-Boot +- Load U-Boot binary using uuu +- Flash U-Boot binary into the eMMC +- Boot + +Get and Build the ARM Trusted Firmware +-------------------------------------- + +.. code-block:: bash + + $ git clone -b imx_4.14.78_1.0.0_ga https://source.codeaurora.org/external/imx/imx-atf + $ cd imx-atf/ + $ make PLAT=imx8qm bl31 + +Get scfw_tcm.bin and ahab-container.img +--------------------------------------- + +.. code-block:: bash + + $ wget https://github.com/toradex/meta-fsl-bsp-release/blob/toradex-sumo-4.14.78-1.0.0_ga-bringup/imx/meta-bsp/recipes- + bsp/imx-sc-firmware/files/mx8qm-apalis-scfw-tcm.bin?raw=true + $ mv mx8qm-apalis-scfw-tcm.bin\?raw\=true mx8qm-apalis-scfw-tcm.bin + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.0.bin + $ chmod +x firmware-imx-8.0.bin + $ ./firmware-imx-8.0.bin + +Copy the following binaries to the U-Boot folder: + +.. code-block:: bash + + $ cp imx-atf/build/imx8qm/release/bl31.bin . + $ cp u-boot/u-boot.bin . + +Copy the following firmware to the U-Boot folder: + +.. code-block:: bash + + $ cp firmware-imx-8.0/firmware/seco/ahab-container.img . + +Build U-Boot +------------ +.. code-block:: bash + + $ make apalis-imx8qm_defconfig + $ make u-boot-dtb.imx + +Load the U-Boot Binary Using UUU +-------------------------------- + +Get the latest version of the universal update utility (uuu) aka ``mfgtools 3.0``: + +https://community.nxp.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2FNXPmicro%2Fmfgtools%2Freleases + +Put the module into USB recovery aka serial downloader mode, connect USB device +to your host and execute uuu: + +.. code-block:: bash + + sudo ./uuu u-boot/u-boot-dtb.imx + +Flash the U-Boot Binary into the eMMC +------------------------------------- + +Burn the ``u-boot-dtb.imx`` binary to the primary eMMC hardware boot area +partition and boot: + +.. code-block:: bash + + load mmc 1:1 $loadaddr u-boot-dtb.imx + setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200 + mmc dev 0 1 + mmc write ${loadaddr} 0x0 ${blkcnt} diff --git a/doc/board/toradex/colibri-imx8x.rst b/doc/board/toradex/colibri-imx8x.rst new file mode 100644 index 0000000000..244e5a4c04 --- /dev/null +++ b/doc/board/toradex/colibri-imx8x.rst @@ -0,0 +1,82 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Colibri iMX8QXP V1.0B Module +============================ + +Quick Start +----------- + +- Build the ARM trusted firmware binary +- Get scfw_tcm.bin and ahab-container.img +- Build U-Boot +- Load U-Boot binary using uuu +- Flash U-Boot binary into the eMMC +- Boot + +Get and Build the ARM Trusted Firmware +-------------------------------------- + +.. code-block:: bash + + $ git clone -b imx_4.14.78_1.0.0_ga https://source.codeaurora.org/external/imx/imx-atf + $ cd imx-atf/ + $ make PLAT=imx8qxp bl31 + +Get scfw_tcm.bin and ahab-container.img +--------------------------------------- +.. code-block:: bash + + $ wget https://github.com/toradex/meta-fsl-bsp-release/blob/ + toradex-sumo-4.14.78-1.0.0_ga-bringup/imx/meta-bsp/recipes- + bsp/imx-sc-firmware/files/mx8qx-colibri-scfw-tcm.bin?raw=true + $ mv mx8qx-colibri-scfw-tcm.bin\?raw\=true mx8qx-colibri-scfw-tcm.bin + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.0.bin + $ chmod +x firmware-imx-8.0.bin + $ ./firmware-imx-8.0.bin + +Copy the following binaries to the U-Boot folder: + +.. code-block:: bash + + $ cp imx-atf/build/imx8qxp/release/bl31.bin . + $ cp u-boot/u-boot.bin . + +Copy the following firmware to the U-Boot folder: + +.. code-block:: bash + + $ cp firmware-imx-8.0/firmware/seco/ahab-container.img . + +Build U-Boot +------------ + +.. code-block:: bash + + $ make colibri-imx8qxp_defconfig + $ make u-boot-dtb.imx + +Load the U-Boot Binary Using UUU +-------------------------------- + +Get the latest version of the universal update utility (uuu) aka ``mfgtools 3.0``: + +https://community.nxp.com/external-link.jspa?url=https%3A%2F%2Fgithub.com%2FNXPmicro%2Fmfgtools%2Freleases + +Put the module into USB recovery aka serial downloader mode, connect USB device +to your host and execute ``uuu``: + +.. code-block:: bash + + sudo ./uuu u-boot/u-boot-dtb.imx + +Flash the U-Boot Binary into the eMMC +------------------------------------- + +Burn the ``u-boot-dtb.imx`` binary to the primary eMMC hardware boot area partition: + +.. code-block:: bash + + load mmc 1:1 $loadaddr u-boot-dtb.imx + setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200 + mmc dev 0 1 + mmc write ${loadaddr} 0x0 ${blkcnt} diff --git a/doc/board/toradex/colibri_imx7.rst b/doc/board/toradex/colibri_imx7.rst new file mode 100644 index 0000000000..6fb9526666 --- /dev/null +++ b/doc/board/toradex/colibri_imx7.rst @@ -0,0 +1,127 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Colibri iMX7 +============ + +Quick Start +----------- + +- Build U-Boot +- NAND IMX image adjustments before flashing +- Flashing manually U-Boot to eMMC +- Flashing manually U-Boot to NAND +- Using ``update_uboot`` script + +Build U-Boot +------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=arm-linux-gnueabi- + $ export ARCH=arm + $ make colibri_imx7_emmc_defconfig # For NAND: colibri_imx7_defconfig + $ make + +After build succeeds, you will obtain final ``u-boot-dtb.imx`` IMX specific +image, ready for flashing (but check next section for additional +adjustments). + +Final IMX program image includes (section ``6.6.7`` from `IMX7DRM +<https://www.nxp.com/webapp/Download?colCode=IMX7DRM>`_): + +* **Image vector table** (IVT) for BootROM +* **Boot data** -indicates the program image location, program image size + in bytes, and the plugin flag. +* **Device configuration data** +* **User image**: U-Boot image (``u-boot-dtb.bin``) + + +IMX image adjustments prior to flashing +--------------------------------------- + +1. U-Boot for both Colibri iMX7 NAND and eMMC versions +is built with HABv4 support (`AN4581.pdf +<https://www.nxp.com/docs/en/application-note/AN4581.pdf>`_) +enabled by default, which requires to generate a proper +Command Sequence File (CSF) by srktool from NXP (not included in the +U-Boot tree, check additional details in introduction_habv4.txt) +and concatenate it to the final ``u-boot-dtb.imx``. + +2. In case if you don't want to generate a proper ``CSF`` (for any reason), +you still need to pad the IMX image so i has the same size as specified in +in **Boot Data** section of IMX image. +To obtain this value, run: + +.. code-block:: bash + + $ od -X -N 0x30 u-boot-dtb.imx + 0000000 402000d1 87800000 00000000 877ff42c + 0000020 877ff420 877ff400 878a5000 00000000 + ^^^^^^^^ + 0000040 877ff000 000a8060 00000000 40b401d2 + ^^^^^^^^ ^^^^^^^^ + +Where: + +* ``877ff400`` - IVT self address +* ``877ff000`` - Program image address +* ``000a8060`` - Program image size + +To calculate the padding: + +* IVT offset = ``0x877ff400`` - ``0x877ff000`` = ``0x400`` +* Program image size = ``0xa8060`` - ``0x400`` = ``0xa7c60`` + +and then pad the image: + +.. code-block:: bash + + $ objcopy -I binary -O binary --pad-to 0xa7c60 --gap-fill=0x00 \ + u-boot-dtb.imx u-boot-dtb.imx.zero-padded + +3. Also, according to requirement from ``6.6.7.1``, the final image +should have ``0x400`` offset for initial IVT table. + +For eMMC setup we handle this by flashing it to ``0x400``, howewer +for NAND setup we adjust the image prior to flashing, adding padding in the +beginning of the image. + +.. code-block:: bash + + $ dd if=u-boot-dtb.imx.zero-padded of=u-boot-dtb.imx.ready bs=1024 seek=1 + +Flash U-Boot IMX image to eMMC +------------------------------ + +Flash the ``u-boot-dtb.imx.zero-padded`` binary to the primary eMMC hardware +boot area partition: + +.. code-block:: bash + + + => load mmc 1:1 $loadaddr u-boot-dtb.imx.zero-padded + => setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200 + => mmc dev 0 1 + => mmc write ${loadaddr} 0x2 ${blkcnt} + +Flash U-Boot IMX image to NAND +------------------------------ + +.. code-block:: bash + + => load mmc 1:1 $loadaddr u-boot-dtb.imx.ready + => nand erase.part u-boot1 + => nand write ${loadaddr} u-boot1 ${filesize} + => nand erase.part u-boot2 + => nand write ${loadaddr} u-boot2 ${filesize} + +Using update_uboot script +------------------------- + +You can also usb U-Boot env update_uboot script, +which wraps all eMMC/NAND specific command invocation: + +.. code-block:: bash + + => load mmc 1:1 $loadaddr u-boot-dtb.imx.ready + => run update_uboot diff --git a/doc/board/toradex/index.rst b/doc/board/toradex/index.rst new file mode 100644 index 0000000000..16b5a0770d --- /dev/null +++ b/doc/board/toradex/index.rst @@ -0,0 +1,12 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Toradex +======= + +.. toctree:: + :maxdepth: 2 + + apalix-imx8 + colibri_imx7 + colibri-imx8x + verdin-imx8mm diff --git a/doc/board/toradex/verdin-imx8mm.rst b/doc/board/toradex/verdin-imx8mm.rst new file mode 100644 index 0000000000..b2ae4fabea --- /dev/null +++ b/doc/board/toradex/verdin-imx8mm.rst @@ -0,0 +1,112 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Verdin iMX8M Mini Module +======================== + +Quick Start +----------- + +- Build the ARM trusted firmware binary +- Get the DDR firmware +- Build U-Boot +- Flash to eMMC +- Boot + +Get and Build the ARM Trusted Firmware (Trusted Firmware A) +----------------------------------------------------------- + +.. code-block:: bash + + $ echo "Downloading and building TF-A..." + $ git clone -b imx_4.14.98_2.3.0 \ + https://source.codeaurora.org/external/imx/imx-atf + $ cd imx-atf + +Please edit ``plat/imx/imx8mm/include/platform_def.h`` so it contains proper +values for UART configuration and BL31 base address (correct values listed +below): + +.. code-block:: bash + + #define BL31_BASE 0x910000 + #define IMX_BOOT_UART_BASE 0x30860000 + #define DEBUG_CONSOLE 1 + +Then build ATF (TF-A): + +.. code-block:: bash + + $ make PLAT=imx8mm bl31 + +Get the DDR Firmware +-------------------- + +.. code-block:: bash + + $ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.4.1.bin + $ chmod +x firmware-imx-8.4.1.bin + $ ./firmware-imx-8.4.1.bin + $ cp firmware-imx-8.4.1/firmware/ddr/synopsys/lpddr4*.bin ./ + +Build U-Boot +------------ +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-linux-gnu- + $ make verdin-imx8mm_defconfig + $ make flash.bin + +Flash to eMMC +------------- + +.. code-block:: bash + + > tftpboot ${loadaddr} flash.bin + > setexpr blkcnt ${filesize} + 0x1ff && setexpr blkcnt ${blkcnt} / 0x200 + > mmc dev 0 1 && mmc write ${loadaddr} 0x2 ${blkcnt} + +As a convenience, instead of the last two commands one may also use the update +U-Boot wrapper: + +.. code-block:: bash + + > run update_uboot + +Boot +---- + +ATF, U-Boot proper and u-boot.dtb images are packed into FIT image, +which is loaded and parsed by SPL. + +Boot sequence is: + +* SPL ---> ATF (TF-A) ---> U-Boot proper + +Output: + +.. code-block:: bash + + U-Boot SPL 2020.01-00187-gd411d164e5 (Jan 26 2020 - 04:47:26 +0100) + Normal Boot + Trying to boot from MMC1 + NOTICE: Configuring TZASC380 + NOTICE: RDC off + NOTICE: BL31: v2.0(release):rel_imx_4.14.98_2.3.0-0-g09c5cc994-dirty + NOTICE: BL31: Built : 01:11:41, Jan 25 2020 + NOTICE: sip svc init + + + U-Boot 2020.01-00187-gd411d164e5 (Jan 26 2020 - 04:47:26 +0100) + + CPU: Freescale i.MX8MMQ rev1.0 at 0 MHz + Reset cause: POR + DRAM: 2 GiB + MMC: FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2 + Loading Environment from MMC... OK + In: serial + Out: serial + Err: serial + Model: Toradex Verdin iMX8M Mini Quad 2GB Wi-Fi / BT IT V1.0A, Serial: + Net: eth0: ethernet@30be0000 + Hit any key to stop autoboot: 0 + Verdin iMX8MM # diff --git a/doc/device-tree-bindings/gpio/intel,apl-gpio.txt b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt index e27a40b437..cf0659b70e 100644 --- a/doc/device-tree-bindings/gpio/intel,apl-gpio.txt +++ b/doc/device-tree-bindings/gpio/intel,apl-gpio.txt @@ -23,7 +23,7 @@ Example: { p2sb: p2sb@d,0 { reg = <0x02006810 0 0 0 0>; - compatible = "intel,apl-p2sb"; + compatible = "intel,p2sb"; early-regs = <IOMAP_P2SB_BAR 0x100000>; north { diff --git a/doc/device-tree-bindings/i2c/i2c-gpio.txt b/doc/device-tree-bindings/i2c/i2c-gpio.txt index ba56ed5dea..b06b829933 100644 --- a/doc/device-tree-bindings/i2c/i2c-gpio.txt +++ b/doc/device-tree-bindings/i2c/i2c-gpio.txt @@ -16,6 +16,10 @@ Optional: The resulting transfer speed can be adjusted by setting the delay[us] between gpio-toggle operations. Speed [Hz] = 1000000 / 4 * udelay[us], It not defined, then default is 5us (~50KHz). +* i2c-gpio,deblock + Run deblocking sequence when the driver gets probed. +* i2c-gpio,scl-output-only; + Set if SCL is an output only Example: diff --git a/doc/device-tree-bindings/misc/bootcounter.txt b/doc/device-tree-bindings/misc/bootcounter.txt new file mode 100644 index 0000000000..d32fbc37b2 --- /dev/null +++ b/doc/device-tree-bindings/misc/bootcounter.txt @@ -0,0 +1,21 @@ +U-Boot bootcounter Devicetree Binding +===================================== + +The device tree node describes the U-Boot bootcounter +memory based device binding. + +Required properties : + +- compatible : "u-boot,bootcount"; +- single-word : set this, if you have only one word space + for storing the bootcounter. + +Example +------- + +MPC83xx based board: + +bootcount@0x13ff8 { + compatible = "u-boot,bootcount"; + reg = <0x13ff8 0x08>; +}; diff --git a/doc/device-tree-bindings/net/ti,dp83867.txt b/doc/device-tree-bindings/net/ti,dp83867.txt deleted file mode 100644 index 268220964a..0000000000 --- a/doc/device-tree-bindings/net/ti,dp83867.txt +++ /dev/null @@ -1,35 +0,0 @@ -* Texas Instruments - dp83867 Giga bit ethernet phy - -Required properties: - - reg - The ID number for the phy, usually a small integer - - ti,rx-internal-delay - RGMII Recieve Clock Delay - see dt-bindings/net/ti-dp83867.h - for applicable values - - ti,tx-internal-delay - RGMII Transmit Clock Delay - see dt-bindings/net/ti-dp83867.h - for applicable values - - ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h - for applicable values - - enet-phy-lane-swap - Indicates that PHY will swap the TX/RX lanes to - compensate for the board being designed with the lanes swapped. - - enet-phy-no-lane-swap - Indicates that PHY will disable swap of the - TX/RX lanes. - - ti,clk-output-sel - Muxing option for CLK_OUT pin. See dt-bindings/net/ti-dp83867.h - for applicable values. The CLK_OUT pin can also - be disabled by this property. When omitted, the - PHY's default will be left as is. - -Default child nodes are standard Ethernet PHY device -nodes as described in doc/devicetree/bindings/net/ethernet.txt - -Example: - - ethernet-phy@0 { - reg = <0>; - ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>; - ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_75_NS>; - ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; - enet-phy-lane-no-swap; - ti,clk-output-sel = <DP83867_CLK_O_SEL_CHN_A_TCLK>; - }; - -Datasheet can be found: -http://www.ti.com/product/DP83867IR/datasheet diff --git a/doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt b/doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt index cd7f8a0ca3..12ec846107 100644 --- a/doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt +++ b/doc/device-tree-bindings/pinctrl/intel,apl-pinctrl.txt @@ -23,7 +23,7 @@ Example: { p2sb: p2sb@d,0 { reg = <0x02006810 0 0 0 0>; - compatible = "intel,apl-p2sb"; + compatible = "intel,p2sb"; early-regs = <IOMAP_P2SB_BAR 0x100000>; n { diff --git a/doc/driver-model/ethernet.rst b/doc/driver-model/ethernet.rst new file mode 100644 index 0000000000..359a0523cf --- /dev/null +++ b/doc/driver-model/ethernet.rst @@ -0,0 +1,321 @@ +Ethernet Driver Guide +======================= + +The networking stack in Das U-Boot is designed for multiple network devices +to be easily added and controlled at runtime. This guide is meant for people +who wish to review the net driver stack with an eye towards implementing your +own ethernet device driver. Here we will describe a new pseudo 'APE' driver. + +Most existing drivers do already - and new network driver MUST - use the +U-Boot core driver model. Generic information about this can be found in +doc/driver-model/design.rst, this document will thus focus on the network +specific code parts. +Some drivers are still using the old Ethernet interface, differences between +the two and hints about porting will be handled at the end. + +Driver framework +------------------ + +A network driver following the driver model must declare itself using +the UCLASS_ETH .id field in the U-Boot driver struct: + +.. code-block:: c + + U_BOOT_DRIVER(eth_ape) = { + .name = "eth_ape", + .id = UCLASS_ETH, + .of_match = eth_ape_ids, + .ofdata_to_platdata = eth_ape_ofdata_to_platdata, + .probe = eth_ape_probe, + .ops = ð_ape_ops, + .priv_auto_alloc_size = sizeof(struct eth_ape_priv), + .platdata_auto_alloc_size = sizeof(struct eth_ape_pdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, + }; + +struct eth_ape_priv contains runtime per-instance data, like buffers, pointers +to current descriptors, current speed settings, pointers to PHY related data +(like struct mii_dev) and so on. Declaring its size in .priv_auto_alloc_size +will let the driver framework allocate it at the right time. +It can be retrieved using a dev_get_priv(dev) call. + +struct eth_ape_pdata contains static platform data, like the MMIO base address, +a hardware variant, the MAC address. ``struct eth_pdata eth_pdata`` +as the first member of this struct helps to avoid duplicated code. +If you don't need any more platform data beside the standard member, +just use sizeof(struct eth_pdata) for the platdata_auto_alloc_size. + +PCI devices add a line pointing to supported vendor/device ID pairs: + +.. code-block:: c + + static struct pci_device_id supported[] = { + { PCI_DEVICE(PCI_VENDOR_ID_APE, 0x4223) }, + {} + }; + + U_BOOT_PCI_DEVICE(eth_ape, supported); + +It is also possible to declare support for a whole class of PCI devices:: + + { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_SDHCI << 8, 0xffff00) }, + +Device probing and instantiation will be handled by the driver model framework, +so follow the guidelines there. The probe() function would initialise the +platform specific parts of the hardware, like clocks, resets, GPIOs, the MDIO +bus. Also it would take care of any special PHY setup (power rails, enable +bits for internal PHYs, etc.). + +Driver methods +---------------- + +The real work will be done in the driver method functions the driver provides +by defining the members of struct eth_ops: + +.. code-block:: c + + struct eth_ops { + int (*start)(struct udevice *dev); + int (*send)(struct udevice *dev, void *packet, int length); + int (*recv)(struct udevice *dev, int flags, uchar **packetp); + int (*free_pkt)(struct udevice *dev, uchar *packet, int length); + void (*stop)(struct udevice *dev); + int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join); + int (*write_hwaddr)(struct udevice *dev); + int (*read_rom_hwaddr)(struct udevice *dev); + }; + +An up-to-date version of this struct together with more information can be +found in include/net.h. + +Only start, stop, send and recv are required, the rest are optional and are +handled by generic code or ignored if not provided. + +The **start** function initialises the hardware and gets it ready for send/recv +operations. You often do things here such as resetting the MAC +and/or PHY, and waiting for the link to autonegotiate. You should also take +the opportunity to program the device's MAC address with the enetaddr member +of the generic struct eth_pdata (which would be the first member of your +own platdata struct). This allows the rest of U-Boot to dynamically change +the MAC address and have the new settings be respected. + +The **send** function does what you think -- transmit the specified packet +whose size is specified by length (in bytes). The packet buffer can (and +will!) be reused for subsequent calls to send(), so it must be no longer +used when the send() function returns. The easiest way to achieve this is +to wait until the transmission is complete. Alternatively, if supported by +the hardware, just waiting for the buffer to be consumed (by some DMA engine) +might be an option as well. +Another way of consuming the buffer could be to copy the data to be send, +then just queue the copied packet (for instance handing it over to a DMA +engine), and return immediately afterwards. +In any case you should leave the state such that the send function can be +called multiple times in a row. + +The **recv** function polls for availability of a new packet. If none is +available, it must return with -EAGAIN. +If a packet has been received, make sure it is accessible to the CPU +(invalidate caches if needed), then write its address to the packetp pointer, +and return the length. If there is an error (receive error, too short or too +long packet), return 0 if you require the packet to be cleaned up normally, +or a negative error code otherwise (cleanup not necessary or already done). +The U-Boot network stack will then process the packet. + +If **free_pkt** is defined, U-Boot will call it after a received packet has +been processed, so the packet buffer can be freed or recycled. Typically you +would hand it back to the hardware to acquire another packet. free_pkt() will +be called after recv(), for the same packet, so you don't necessarily need +to infer the buffer to free from the ``packet`` pointer, but can rely on that +being the last packet that recv() handled. +The common code sets up packet buffers for you already in the .bss +(net_rx_packets), so there should be no need to allocate your own. This doesn't +mean you must use the net_rx_packets array however; you're free to use any +buffer you wish. + +The **stop** function should turn off / disable the hardware and place it back +in its reset state. It can be called at any time (before any call to the +related start() function), so make sure it can handle this sort of thing. + +The (optional) **write_hwaddr** function should program the MAC address stored +in pdata->enetaddr into the Ethernet controller. + +So the call graph at this stage would look something like: + +.. code-block:: c + + (some net operation (ping / tftp / whatever...)) + eth_init() + ops->start() + eth_send() + ops->send() + eth_rx() + ops->recv() + (process packet) + if (ops->free_pkt) + ops->free_pkt() + eth_halt() + ops->stop() + + +CONFIG_PHYLIB / CONFIG_CMD_MII +-------------------------------- + +If your device supports banging arbitrary values on the MII bus (pretty much +every device does), you should add support for the mii command. Doing so is +fairly trivial and makes debugging mii issues a lot easier at runtime. + +In your driver's ``probe()`` function, add a call to mdio_alloc() and +mdio_register() like so: + +.. code-block:: c + + bus = mdio_alloc(); + if (!bus) { + ... + return -ENOMEM; + } + + bus->read = ape_mii_read; + bus->write = ape_mii_write; + mdio_register(bus); + +And then define the mii_read and mii_write functions if you haven't already. +Their syntax is straightforward:: + + int mii_read(struct mii_dev *bus, int addr, int devad, int reg); + int mii_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val); + +The read function should read the register 'reg' from the phy at address 'addr' +and return the result to its caller. The implementation for the write function +should logically follow. + +................................................................ + +Legacy network drivers +------------------------ + +!!! WARNING !!! + +This section below describes the old way of doing things. No new Ethernet +drivers should be implemented this way. All new drivers should be written +against the U-Boot core driver model, as described above. + +The actual callback functions are fairly similar, the differences are: + +- ``start()`` is called ``init()`` +- ``stop()`` is called ``halt()`` +- The ``recv()`` function must loop until all packets have been received, for + each packet it must call the net_process_received_packet() function, + handing it over the pointer and the length. Afterwards it should free + the packet, before checking for new data. + +For porting an old driver to the new driver model, split the existing recv() +function into the actual new recv() function, just fetching **one** packet, +remove the call to net_process_received_packet(), then move the packet +cleanup into the ``free_pkt()`` function. + +Registering the driver and probing a device is handled very differently, +follow the recommendations in the driver model design documentation for +instructions on how to port this over. For the records, the old way of +initialising a network driver is as follows: + +Old network driver registration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When U-Boot initializes, it will call the common function eth_initialize(). +This will in turn call the board-specific board_eth_init() (or if that fails, +the cpu-specific cpu_eth_init()). These board-specific functions can do random +system handling, but ultimately they will call the driver-specific register +function which in turn takes care of initializing that particular instance. + +Keep in mind that you should code the driver to avoid storing state in global +data as someone might want to hook up two of the same devices to one board. +Any such information that is specific to an interface should be stored in a +private, driver-defined data structure and pointed to by eth->priv (see below). + +So the call graph at this stage would look something like: + +.. code-block:: c + + board_init() + eth_initialize() + board_eth_init() / cpu_eth_init() + driver_register() + initialize eth_device + eth_register() + +At this point in time, the only thing you need to worry about is the driver's +register function. The pseudo code would look something like: + +.. code-block:: c + + int ape_register(bd_t *bis, int iobase) + { + struct ape_priv *priv; + struct eth_device *dev; + struct mii_dev *bus; + + priv = malloc(sizeof(*priv)); + if (priv == NULL) + return -ENOMEM; + + dev = malloc(sizeof(*dev)); + if (dev == NULL) { + free(priv); + return -ENOMEM; + } + + /* setup whatever private state you need */ + + memset(dev, 0, sizeof(*dev)); + sprintf(dev->name, "APE"); + + /* + * if your device has dedicated hardware storage for the + * MAC, read it and initialize dev->enetaddr with it + */ + ape_mac_read(dev->enetaddr); + + dev->iobase = iobase; + dev->priv = priv; + dev->init = ape_init; + dev->halt = ape_halt; + dev->send = ape_send; + dev->recv = ape_recv; + dev->write_hwaddr = ape_write_hwaddr; + + eth_register(dev); + + #ifdef CONFIG_PHYLIB + bus = mdio_alloc(); + if (!bus) { + free(priv); + free(dev); + return -ENOMEM; + } + + bus->read = ape_mii_read; + bus->write = ape_mii_write; + mdio_register(bus); + #endif + + return 1; + } + +The exact arguments needed to initialize your device are up to you. If you +need to pass more/less arguments, that's fine. You should also add the +prototype for your new register function to include/netdev.h. + +The return value for this function should be as follows: +< 0 - failure (hardware failure, not probe failure) +>=0 - number of interfaces detected + +You might notice that many drivers seem to use xxx_initialize() rather than +xxx_register(). This is the old naming convention and should be avoided as it +causes confusion with the driver-specific init function. + +Other than locating the MAC address in dedicated hardware storage, you should +not touch the hardware in anyway. That step is handled in the driver-specific +init function. Remember that we are only registering the device here, we are +not checking its state or doing random probing. diff --git a/doc/driver-model/index.rst b/doc/driver-model/index.rst index 6d55774b4c..b9df221627 100644 --- a/doc/driver-model/index.rst +++ b/doc/driver-model/index.rst @@ -8,6 +8,7 @@ Driver Model debugging design + ethernet fdt-fixup fs_firmware_loader i2c-howto diff --git a/doc/uefi/uefi.rst b/doc/uefi/uefi.rst index a8fd886d6b..cfe2d84a4c 100644 --- a/doc/uefi/uefi.rst +++ b/doc/uefi/uefi.rst @@ -356,6 +356,18 @@ This driver is only available if U-Boot is configured with:: CONFIG_BLK=y CONFIG_PARTITIONS=y +Miscellaneous +------------- + +Load file 2 protocol +~~~~~~~~~~~~~~~~~~~~ + +The load file 2 protocol can be used by the Linux kernel to load the initial +RAM disk. U-Boot can be configured to provide an implementation with:: + + EFI_LOAD_FILE2_INITRD=y + EFI_INITRD_FILESPEC=interface dev:part path_to_initrd + Links ----- |