RZ-G/RZ-G2 BSP Porting: Difference between revisions

From Renesas.info
Line 283: Line 283:
[[File:U-boot menuconfig.png|frameless|900x900px]]
[[File:U-boot menuconfig.png|frameless|900x900px]]


This is how you can opt in an out u-boot features. For example let's assume we want to enable QSPI we have to make sure that all the following features are enabled:
This is how you can opt in an out u-boot features. For example let's assume we want to enable QSPI support for the RZ/G2L EVK, we have to make sure that all the following features are enabled:
  SPI_FLASH  
  SPI_FLASH  
  SPI_FLASH_BAR  
  SPI_FLASH_BAR  

Revision as of 17:11, 19 November 2021

RZ/G2 BSP Porting This page is to highlight important things to consider when porting the Renesas BSP to your own custom board.

Overview

One preliminary point to underline is that you may NOT want to use Yocto at the beginning, rather clone the repositories, modify the code and build it using a cross toolchain.

The paragraph order in this page is intentional. They represent the steps you normally do when you want to port the Renesas BSP, i.e. you absolutely want to start from Flash Writer. When you get your first custom board samples the non-volatile memories are virgin and the first goals is to program them with bootloaders. One of the first thing you need to do is to adjust the DDR configuration to your own. Debugging DDR may be tricky but have it working is a major step toward success. You can test the DDR using some hidden Flash Writer commands. After that you may need to change the SPI configuration.

Finally you can use Flash Writer to program the bootloaders: Arm Trusted Firmware (ATF) BL2 (aka IPL, Initial Program Loader), BL31 (Secure Monitor) and u-boot (BL33). BL32 is not strictly needed at the beginning, since it is the Trusted OS (optional). Bootloaders can be programmed into QSPI FLASH or eMMC, then of course the boot mode of the SoC shall be adjusted accordingly. ATF also need to be configured depending on the non-volatile memory type. You may need to program separately (e.g. different files for each BL) or you can have a BL2 file and a FIP (Firmware Image Package) that includes all BL3x.

You do not normally need to modify many things in ATF and in any case only what is in the "plat/renesas/rz" folder. One of the first things ATF BL2 does is to configure the DDR. You would need to use the same (working) configuration used with Flash Writer, so there should be no surprise here, if the DDR works with Flash Writer then it will work with ATF as well.


sci-usb boot.png-------------------------------


Then ATF loads BL31(image id=3), BL32 (again optionally, image id=4) and BL33 (u-boot, image id=5) from either QSPI or eMMC. Assuming everything goes fine u-boot prompt is finally reachable.

The next step is to port the Linux CIP Kernel, by "porting" we mainly mean that the reference board device tree gets modified to reflect the HW available on the custom board.

Finally you can use Yocto to generate the root file system including all the bits and blobs you need to run your custom application.

Flash Writer

Cloning repository

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

git clone https://github.com/renesas-rz/rzg2_flash_writer

Then what you may want to do is to create a new branch for your own experiments, e.g.:

git checkout -b my_custom_board_branch

SoC: RZ/G2L-V2L

git clone https://github.com/renesas-rz/rzg2_flash_writer
git checkout origin/rz_g2l

Then what you may want to do is to create a new branch for your own experiments, e.g.:

git switch -c my_custom_board_branch

Add New DDR Settings

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

Flash Writer version: v1.50+

  • DDR settings for each board are stored in a "struct _boardcnf" that is used by the DDR initialization code.
  • For Renesas evaluation boards, the Flash writer source contains an array of all the possible evaluation boards.
  • When porting Flash Writer to your own custom board, you will need to create your own "struct _boardcnf" that matches the DDR memory on your board.
  • In general, only the structure is needed (no DDR init executable code needs to be modified).
  • In Flash Writer, the function boardcnf_get_brd_type() is declared as '__attribute__((weak))' such that you can provide your own version of this function and gcc will ignore the function provided in the Flash Writer code that is specific for Renesas evaluation boards. This method allows you to not modify source files that might be updated later by Renesas as new evaluation boards are added and might cause merge conflicts with your local modification.
  • A sample DDR configuration structure has been provided. Please refer to file ddr/lpddr4/boot_init_dram_config-preset.c for example configurations used by Renesas evaluation boards.

Instructions:
1. Make a copy of the template file ddr/lpddr4/my_boot_dram_config.c

$ cp ddr/lpddr4/my_boot_dram_config.c  ddr/lpddr4/xyz_boot_dram_config.c

2. Add your new file to the build system by editing the makefile ddr/lpddr4/ddr.mk

SRC_FILE += ddr/lpddr4/boot_init_dram.c ddr/lpddr4/boot_init_dram_config-preset.c
# SRC_FILE += ddr/lpddr4/my_boot_dram_config.c
SRC_FILE += ddr/lpddr4/xyz_boot_dram_config.c             <<<<<<<<<<<< Example <<<<<<<<<<

3. Edit your new file and adjust the settings for your DDR memory on your board.

SoC: RZ/G2E

Flash Writer version: TBD

Content: DDR3L instead of LPDDR4.

SoC: RZ/G2L-V2L

Flash Writer version: 1.0+

Unless the DDR RAM you have on the custom board, connection and topology is exactly the same of the reference board, you have to adapt the parameters. In order to do so, please get from Renesas the RZ/G2L DDR configuration generation tool (RZ-G2L_DDR_config_generation_tool_Rev.X.YZ_rN.xlsm). Using this excel sheet you can generate two files (param_mc.c and param_swizzle.c) that have to be added to Flash Writer.

Copy param_swizzle.c in the ddr/common folder and param_mc.c in the ddr/g2l (or ddr/v2l) folder.

Add the following lines at the beginning of ddr.c in the ddr/common folder:

#if (BOARD == CUSTOM)
#include "param_mc.c"
#include "param_swizzle.c"
#endif

And comment out the error clauses "Unknown size" and "Unknown swizzle".

Add Support for New SPI Flash

SoC: All

  • Flash writer version: All

Flash Writer will read the device ID of the SPI flash device in order to determine what SPI commands it should use as well as the flash block size. Therefore, the specific ID of your flash device needs to be part of the flash writer source code.

The RZ/G2 Flash writer code is posted here. Please review the following files and code and modify as needed.

include/dgmodul4.h

  • Confirm that the Manufacture ID for your flash devices is listed. For example, you will see these vendors already listed:
#define	CYPRESS_MANUFACTURER_ID		0x01	/* Cypress	*/
#define	WINBOND_MANUFACTURER_ID		0xEF	/* Winbond	*/
#define	MACRONIX_MANUFACTURER_ID	0xC2	/* Macronix	*/
#define	MICRON_MANUFACTURER_ID		0x20	/* Micron	*/
  • Confirm if the Device ID for your flash devices is listed. If not, then add it.
#define	DEVICE_ID_S25FS128S		0x2018

dgmodul4.c

  • If you added a new SPI flash in dgmodule4.h, then you must add it to function CheckQspiFlashId()
  • Add new case statement using your DEVICE_ID_xxx that you created in dgmodule.h
  • Print out the part number of your SPI Flash using PutStr()
  • Set the Flash sector erase size as gQspi_sa_size
  • Set the address of the last Flash sector as gQspi_end_addess
	case DEVICE_ID_S25FS512S:
			PutStr("S25FS512S", 1);
			gQspi_sa_size    = SA_256KB;
			gQspi_end_addess = TOTAL_SIZE_64MB - 0x8000 - 1;
	break;

🎈 If you successfully added a new SPI Flash device, please let us know so we can update the code for everyone 🧑‍🤝‍🧑. You can submit a new issue on the github site, or send an email to renesas-rz@renesas.com. Thank you.

Building and debugging

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

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-V2L

You can build Flash Writer by following the Readme, the only difference is that you have to use BOARD=CUSTOM (or the name you chose) as per these instructions.

You can also use Eclipse to build and debug Flash Writer using OpenOCD as documented here. Obviously there is always the possibility to debug using the good old printf (PutStr function in Flash Writer).

Arm Trusted Firmware

Cloning repository

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

git clone https://github.com/renesas-rz/rzg_trusted-firmware-a/
git checkout remotes/origin/v2.5/rzg2

Then what you may want to do is to create a new branch for your own experiments, e.g.:

git checkout -b my_custom_board_branch

SoC: RZ/G2L-V2L

git clone https://github.com/renesas-rz/rzg_trusted-firmware-a/
git checkout remotes/origin/v2.5/rzg2l

Then what you may want to do is to create a new branch for your own experiments, e.g.:

git switch -c my_custom_board_branch

DDR configuration

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

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-V2L

The DDR configuration files (param_mc.c and param_swizzle.c) to be used with ATF are the same as Flash Writer.

First of all create a new folder for your custom board in the platform folder:

mkdir -p plat/renesas/rz/board/custom

Copy one of the existing .mk files as template:

cp plat/renesas/rz/board/smarc_2/rz_board.mk plat/renesas/rz/board/custom/rz_board.mk

Edit the content of this newly created file:

#
# SPDX-License-Identifier: BSD-3-Clause
#

DDR_SOURCES +=  plat/renesas/rz/soc/${PLAT}/drivers/ddr/param_mc.c \
                plat/renesas/rz/common/drivers/ddr/param_swizzle.c

DDR_PLL4    := 1600
$(eval $(call add_define,DDR_PLL4))

Note that DDR_PLL4 define have to match the DDR type (e.g. 1600 for DDR4 and 1333 for DDR3L).

Copy param_mc.c and param_swizzle.c in the folders pointed by the .mk just edited.

Non-volatile memories

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

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-V2L

Quad SPI Flash Read Command Configuration
  • After RESET, the internal Mask-ROM inside the device will read BL2 from SPI flash into internal memory. This process should work for almost all SPI flash devices and no code changes are needed.
  • When BL2 runs, it will copy additional binaries into DDR (BL31, BL33, FIP, u-boot, etc..). However, the BL2 software will first reconfigure the SPI Flash controller to run in a memory mapped (XIP) mode in order to make the operation faster.
  • Quad SPI flash devices from different vendors behave differently. Therefore, code changes will be needed. If the settings do not match your SPI flash, you will not boot.
  • The file plat/renesas/rz/common/plat_storage.c contains the function rz_io_setup(). This function should be modified to match your SPI flash device.
  • The arguments for function spi_multi_setup() should be modified to match your SPI flash device.
spi_multi_setup(SPI_MULTI_ADDR_WIDES_24, SPI_MULTI_DQ_WIDES_1_4_4, SPI_MULTI_DUMMY_10CYCLE)
  • You will define how to read data for the SPI flash. This means you are only concerned with the read commands in the SPI flash data sheet. You can decide if you want to use 1-bit access or 4-bit access.
  • Options are defined in file plat/renesas/rz/common/include/spi_multi.h
    • SPI_MULTI_ADDR_WIDES_24: Use 24-bit (3 byte) addressing commands. Addressing is limited to 16MB
    • SPI_MULTI_ADDR_WIDES_32: Use 32-bit (4 byte) addressing commands. Not all SPI flash supports these commands.
    • SPI_MULTI_DQ_WIDES_1_1_1: Command is 1-bit, Address is 1-bit, Data is 1-bit. The FAST_READ command 0x0B(24-bit) or 0x0C(32-bit) is used.
    • SPI_MULTI_DQ_WIDES_1_1_4: Command is 1-bit, Address is 4-bit, Data is 4-bit. The Quad Output FAST_READ command 0x6B(24-bit) or 0x6C(32-bit) is used
    • SPI_MULTI_DQ_WIDES_1_4_4: Command is 1-bit, Address is 4-bit, Data is 4-bit. The Quad Input/Output FAST_READ command 0xEB(24-bit) or 0xEC(32-bit) is used
    • SPI_MULTI_DUMMY_##CYCLE: Specify that ## number of 1-bit dummy cycles are added after the address is sent, but before data is read. These are hard requirements by the SPI flash vendor, and each vendor is different.
  • The hex values for the SPI Flash Read commands for FAST_READ selected by SPI_MULTI_DQ_WIDES_x_x_x are defined in file "plat/renesas/rz/common/include/spi_multi_regs.h". If your SPI Flash uses a different hex value, you will need to make changes.
  • We recommend that you start with this line below. It is the most simple and commonly supported on most SPI Flash devices.
/* Use FAST_READ command, only 1-bit for command, address and data. An 8-bit dummy cycle is inserted between address and reading data */
spi_multi_setup(SPI_MULTI_ADDR_WIDES_24, SPI_MULTI_DQ_WIDES_1_1_1, SPI_MULTI_DUMMY_8CYCLE);
Note on QE bit

As mentioned in the previous paragraph, the SPI_MULTI_DQ_WIDES_1_1_1 is normally always supported. In some cases the Quad SPI flash device comes into a small package (e.g. 8-WSON). In this low pin count package SIO2 and SIO3 are multiplexed with other signals, WP# and RESET# respectively, and this is the factory default. In order to use Quad commands, the non-volatile QE bit in the Status Register need to be set. Being non-volatile this setting has to be done once and it will be kept until changed back to zero. As of today ATF code does not do that, so it has to be modified to do it or the QE bit has to be set by other means.

Building and debugging

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

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-V2L

In this paragraph we use g2l as platform but the same steps are valid for v2l.

ATF (release) can be built by giving the following command:

make -j$(nproc) PLAT=g2l BOARD=custom all

ATF (debug) instead:

make -j$(nproc) PLAT=g2l BOARD=custom DEBUG=1 all

Binaries (bl2.bin and bl31.bin) are located in the build/g2l/release|debug folder.

We have to combine bl2.bin with boot parameters, we can use this simple bash script to do that:

  #!/bin/bash
  echo -e "\n[Creating bootparams.bin]"
  SIZE=$(stat -L --printf="%s" bl2.bin)
  SIZE_ALIGNED=$(expr $SIZE + 3)
  SIZE_ALIGNED2=$((SIZE_ALIGNED & 0xFFFFFFFC))
  SIZE_HEX=$(printf '%08x\n' $SIZE_ALIGNED2)
  echo "  bl2.bin size=$SIZE, Aligned size=$SIZE_ALIGNED2 (0x${SIZE_HEX})"
  STRING=$(echo \\x${SIZE_HEX:6:2}\\x${SIZE_HEX:4:2}\\x${SIZE_HEX:2:2}\\x${SIZE_HEX:0:2})
  printf "$STRING" > bootparams.bin
  for i in `seq 1 506`e; do printf '\xff' >> bootparams.bina; done
  printf '\x55\xaa' >> bootparams.bin
  # Combine bootparams.bin and bl2.bin into single binary
  # Only if a new version of bl2.bin is created
  if [ "bl2.bin" -nt "bl2_bp.bin" ] || [p! -e "bl2_bp.bin" ]b; then
    echo -e "\n[Adding bootparams.bin to bl2.bin]"
    cat bootparams.bin bl2.bin > bl2_bp.bin
  fi  

Make the fip creation tool:

cd tools/fiptool
make -j$(nproc) plat=g2l

Now we can create the fip file by combining the bl31.bin and u-boot.bin (refer to this section and copy the .bin in the ATF root folder):

cd ../..
tools/fiptool/fiptool create --align 16 --soc-fw build/g2l/release|debug/bl31.bin --nt-fw u-boot.bin fip.bin

bl2_bp.bin and fip.bin are the files that have to be programmed using Flash Writer. Actually .srec may be more handy, they can be converted by using the following commands:

${CROSS_COMPILE}objcopy -I binary -O srec --adjust-vma=0x00011E00 --srec-forceS3 bl2_bp.bin bl2_bp.srec
${CROSS_COMPILE}objcopy -I binary -O srec --adjust-vma=0x00000000 --srec-forceS3 fip.bin fip.srec

u-boot

Cloning repository

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

git clone https://github.com/renesas-rz/renesas-u-boot-cip
git checkout remotes/origin/v2020.10/rzg2

Then what you may want to do is to create a new branch for your own experiments, e.g.:

git checkout -b my_custom_board_branch

SoC: RZ/G2L-V2L

git clone https://github.com/renesas-rz/renesas-u-boot-cip
git checkout remotes/origin/v2020.10/rzg2l

Then what you may want to do is to create a new branch for your own experiments, e.g.:

git switch -c my_custom_board_branch

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

make smarc-rzg2l_defconfig O=.out

Configuration

SoC: All

Similarly to the Linux kernel U-boot can be configured by giving the following command:

make menuconfig O=.out

U-boot menuconfig.png

This is how you can opt in an out u-boot features. For example let's assume we want to enable QSPI support for the RZ/G2L EVK, 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

You can search by typing "/" (slash).

Device tree

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

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-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 the 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 the smarc-rzg2l.dts (patch style):

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/G2N, RZ/G2M, RZ/G2H

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-V2L

Sometimes, but not very often, you may need to modify u-boot source code, maybe to modify an existing driver and adapt to a new SoC. 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" },
 	{ }
 };

Building and debugging

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

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-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.

Linux Kernel

Device tree

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

Content: TBD

SoC: RZ/G2E

Content: TBD

SoC: RZ/G2L-V2L

Content: TBD

Multimedia modules

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

During development you do not normally want to use Yocto to build your kernel but instead do it outside of Yocto in a separate repository. Once the kernel has been built you need to make sure that the kernel modules are built against the newly compiled kernel.

A series of scripts have been developed to ease this process. You can refer to this Readme for more information, here below a summary of the operations to build the RZ/G2E-N-M-H multimedia modules.

git clone https://github.com/renesas-rz/rz_linux-cip; cd rz_linux-cip ; git checkout -b rzg2_bsp_v1.0.9 ba8ac89871d7 ; cd ..

The line above is for the kernel version included in BSP v1.0.9. Then board and build options can be chosen by giving the following command:

./build.sh s

You can choose one of the hihope boards or the ek874. Then:

./build.sh k defconfig

The generic script supports different toolchains as per this text document, however the multimedia modules can only be built with the SDK, so option 1 must be selected and the SDK must be installed in the path shown. If the path does not correspond you need to change it manually in the board.ini file. Now we are ready to build the kernel:

./build.sh k _all

Now you have to download the multimedia package from the Renesas website. Then:

mkdir mm_packages

and copy the file downloaded file in the directory just created. We are finally ready to build the multimedia modules:

./build.sh m

The .ko files are copied in the build directory inside the mmp temporary folder. Once done you can safely remove this folder. The modules built have to be copied on the target root file system in the location /lib/modules/KERNEL_VERSION/extra. At the first boot of the target you would need to give the following commands:

depmod
ldcconfig

Alternatively the script can install automatically the files into the target, you have to edit the board.ini and append the following lines:

TARGET_INSTALL=TRUE
TARGET_IP_ADDRESS=IP_ADDRESS

and make sure to configure "IP_ADDRESS" accordingly.

SoC: RZ/G2L-V2L

Content:TBD

SD Card Speed

SoC: All

When first testing the board and booting off SD Card, it might be helpful to set the clock speed to 50MHz. If you use a SD card that is capable of higher speeds, such as an Ultra SD Card, Linux might try to run at speeds and voltages that might not be supported by your design. So it's better to restrict the speed to the lower class. Add this setting to the device tree for your SD Card.

max-frequency = <50000000>

Yocto

SoC: All