RZ/G2 BSP Porting - u-boot

From Renesas.info

← Back to RZ-G/RZ-G2_BSP_Porting


Source Code Repository

The source code for u-boot is stored on github.

Refer to the table in the wiki section of the repository to determine which branch you should use based on your SoC.

After you clone the repository and check out the correct branch, you may want to do is to create a new branch for your edits. This will make it easier to pull in future updates.

Example:

$ git clone https://github.com/renesas-rz/renesas-u-boot-cip
$ cd renesas-u-boot-cip
$ git checkout v2021.10/rzz
$ git checkout -b my_board     # This will make a new branch named 'my_board'

Add custom board files

SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H

Content: TBD

SoC: RZ/G2L, RZ/V2L

1) Add you custom board device tree file in the arch/arm/dts folder: my_custom_board.dts. You do not need to create this file from scratch, you can copy the Renesas board file as template:

cp arch/arm/dts/smarc-rzg2l.dts arch/arm/dts/my_custom_board.dts

and edit the file arch/arm/dts/Makefile:

[...] 
	rzg2lc-dev.dtb \
-	smarc-rzg2lc.dtb
+	smarc-rzg2lc.dtb \
+	my_custom_board.dtb
 
 ifdef CONFIG_RCAR_GEN3

[...]

2) You need to create the custom board support directory: board/<vendor>/my_custom_board, that would need to be populated with Kconfig, Makefile and my_custom_board.c:

mkdir -p board/<vendor>/my_custom_board
cp board/renesas/rzg2l-dev/* board/<vendor>/my_custom_board
mv board/<vendor>/my_custom_board/rzg2l-dev.c board/<vendor>/my_custom_board/my_custom_board.c

3) Edit the newly created files, board/<vendor>/my_custom_board/Kconfig:

if TARGET_MY_CUSTOM_BOARD

config SYS_SOC
        default "rmobile"

config SYS_BOARD
        default "my_custom_board"

config SYS_VENDOR
        default "<vendor>"

config SYS_CONFIG_NAME
        default "my_custom_board"

endif

Now board/<vendor>/my_custom_board/Makefile to rename the object file related to the .c file:

#
# board/<vendor>/my_custom_board/Makefile
#
# Copyright (C) 2015 Renesas Electronics Corporation
#
# SPDX-License-Identifier: GPL-2.0+
#

ifdef CONFIG_SPL_BUILD
obj-y   := ../../renesas/rcar-common/gen3-spl.o
else
obj-y   := my_custom_board.o ../../renesas/rcar-common/common.o
endif

Then board/<vendor>/my_custom_board.c file could be left unchanged, at least at the first stages. Of course you might need to modify it later on.

4) Next step is the board configuration:

cp configs/rzg2l-dev_defconfig configs/<vendor>_my_custom_board_defconfig 

5) Finally board header file: include/configs/my_board.h. Again, you can take the Renesas files as template:

cp include/configs/smarc-rzg2l.h include/configs/my_custom_board.h

This is the file you want to edit to configure, among other things, different parameters like default extra u-boot environment variables and boot command.

6) Now that we created all the new custom board files, we have to modify the arch Kconfig, arch/arm/mach-rmobile/Kconfig.64, to include your board:

[...]
 config TARGET_SMARC_RZG2LC
 	bool "RZ/G2LC SMARC board"
 	help
           Support for Renesas RZ/G2LC Dev Platform
 
+config TARGET_MY_CUSTOM_BOARD
+        bool "RZ/G2L my stunning custom board"
+        help
+          This is a test custom board with RZ/G2L
+
 endchoice
 
 config SYS_SOC
 	default "rmobile"

[...]
 
 source "board/renesas/ulcb/Kconfig"
 source "board/beacon/beacon-rzg2m/Kconfig"
 source "board/renesas/rzg2l-dev/Kconfig"
 source "board/renesas/rzv2l-dev/Kconfig"
 source "board/renesas/rzg2lc-dev/Kconfig"
+source "board/<vendor>/my_custom_board/Kconfig"

Now we have to create the default configuration, assuming we want to use the .out as output directory:

make <vendor>_my_custom_board_defconfig O=.out

Configuration

SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H

Content: TBD

SoC: RZ/G2L, RZ/V2L

Regarding u-boot configuration, similarly to the Linux kernel U-boot can be configured by giving the following command:

make menuconfig O=.out

U-boot menuconfig.png

You can search by typing "/" (slash). Firstly you need to change the default fdt file (search DEFAULT_FDT_FILE) to reflect the board name:

u-boot fdt.png

And select your custom board as target (search MY_CUSTOM_BOARD):

u-boot board selection.png

Select also my_custom_board as default device tree (search DEFAULT_DEVICE_TREE):

u-boot default device tree.png

In general this is how you can opt in and out any u-boot feature. For example let's assume we also want to enable QSPI support for your custom board, similarly to what just done we have to make sure that all the following features are enabled:

SPI_FLASH 
SPI_FLASH_BAR 
SPI_FLASH_USE_4K_SECTORS 
SPI 
DM_SPI 
SPI_FLASH_WINBOND
RENESAS_RPC_SPI
CMD_SF 
CMD_SPI 
SPI_FLASH_STMICRO
DM_SPI_FLASH

Once you're happy with the configuration changes, you can save the configuration file:

make savedefconfig O=.out
cp .out/defconfig configs/<vendor>_my_custom_board_defconfig

u-boot environment variables

In the configuration it is also possible to specify some options about environment variables:

CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_MMC_ENV_DEV=0
CONFIG_SYS_MMC_ENV_PART=2
CONFIG_ENV_SIZE=0x20000
CONFIG_ENV_OFFSET=0xFFFE0000

CONFIG_SYS_MMC_ENV_DEV: It specifies which MMC device has to be used to store the environment variables;

CONFIG_SYS_MMC_ENV_PART: which MMC area (0=user, 1=boot 1, 2=boot 2);

CONFIG_ENV_SIZE: as the name suggests, size;

CONFIG_ENV_OFFSET: this is the offset in the partition chosen, a negative value is treated as a backwards offset from the end of the eMMC device/partition, rather than a forwards offset from the start.

Note that it is also possible to store them into other memories, e.g QSPI.

Device tree

File Location

  • Like the Linux kernel, u-boot uses a Device Tree to configure device. The Device Tree for the u-boot is supposed to use the same names and syntax as the kernel to make them as compatible as possible.
  • The location for the Device Tree .dts files are: arch/arm/dts/

Adding Your Own Device Tree to the Build

  • When porting u-boot to your own board, you should create your own Device Tree File (.dts).
  • To start, simply copy a Device Tree file (.dts) file for a Renesas evaluation with the same device on your board.
  • Once you've copied/renamed and created your new .dts file, you will need to add it to the Makefile in the arch/arm/dts/ directory.
    • arch/arm/dts/Makefile
  • The Renesas RZ device are in the group CONFIG_RCAR_GEN3. You if you search for that name, you will find all the Device Trees for all the Renesas evaluation boards.
  • To add your new .dts board, you can simple add this line anywhere in the file.
dtb-$(CONFIG_RCAR_GEN3) += my_custom_board.dts

Selecting your Device Tree as the Default to Use

  • By adding your .dts file to the Makefile, it simply compiles the .dts file into a binary (also called a Flattened Device Tree Blob, .dtb)
  • The u-boot image you load into your board is a combination for u-boot.bin + .dtb (a single binary).
  • You select the Device Tree Blob you want to append during the build by setting DEFAULT_FDT_FILE and DEFAULT_DEVICE_TREE in u-boot configuration as explained in the previous section.

SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H

Content: TBD

SoC: RZ/G2L, RZ/V2L

Apart from features that can be enabled/disabled using menuconfig, another very common thing you may need to touch is the device tree, in a similar fashion you would do for the Linux kernel.

Here below an example on how your custom device tree should be modified to enable the SPI Multi I/O Bus Controller (aka RPC) in the RZ/G2L BSP v1.3 that does not officially support it. Newer versions may have these changes already implemented but the example per se is still valid.

The device trees are stored in the folder arch/arm/dts. In this example we have to modify my_custom_board.dts (patch style) as per below:

[...]

aliases {
 		serial0 = &scif0; 
+		spi0 = &spibsc; 	
}; 

[...]

+&spibsc { 
+	num-cs = <1>; 
+	status = "okay"; 
+	spi-max-frequency = <40000000>; 
+	#address-cells = <1>; +	#size-cells = <0>; 
+ 
+	flash0: spi-flash@0 { 
+		#address-cells = <1>; 
+		#size-cells = <1>; 
+		compatible = "spi-flash", "jedec,spi-nor"; 
+		spi-max-frequency = <40000000>; 
+		spi-tx-bus-width = <1>; 
+		spi-rx-bus-width = <1>; 
+		reg = <0>; 
+		status = "okay"; 
+	}; 
+};

[...]

Source code modification

SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H

Content: TBD

SoC: RZ/G2L, RZ/V2L

Sometimes, but not very often, you may need to modify u-boot source code, maybe to modify an existing driver. Following the same example as the previous section, in order to get the QSPI working we have to modify the RPC driver (drivers/spi/renesas_rpc_spi.c) and add a line for RZ/G2L:

[...]
 
	{ .compatible = "renesas,rpc-r8a77995" },
 	{ .compatible = "renesas,rpc-r7s72100" },
+	{ .compatible = "renesas,r9a07g044l-spibsc" },
 	{ }
 };

[...] 

u-boot environment variables

Among many other other parameters, u-boot default environment variables can be configured in the already mentioned:

include/configs/my_custom_board.h

CONFIG_EXTRA_ENV_SETTINGS and CONFIG_BOOTCOMMAND are what you might want to customize.

Building and debugging

SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H

Content: TBD

SoC: RZ/G2L, RZ/V2L

Once we are happy with the modifications (configuration, device tree, source code), to build u-boot simply:

make -j$(nproc) O=.out

The binaries will be located in the .out folder and u-boot.bin is the file you want to combine with bl31.bin using the fip tool, please refer to this section.