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

From Renesas.info
(Added explanation for modification of console port.)
 
(35 intermediate revisions by 5 users not shown)
Line 1: Line 1:
'''RZ/G2 BSP Porting'''
{{DISPLAYTITLE:RZ/G and RZ/V BSP Porting}}
 
This page is to highlight important things to consider when porting the Renesas BSP to your own custom board.
This page is to highlight important things to consider when porting the Renesas BSP to your own custom board.


== Overview ==
== Overview ==
There is s a '''RZ/G2 Group Linux BSP Porting Guide''' document posted on Renesas.com.
* https://www.renesas.com/us/en/document/mas/rzg2-group-linux-bsp-porting-guide
This document contains information such as:
* How to add a new build configuration for a new board to a Yocto
* How to add a new build configuration for a new board to a u-boot
* Information about configuring pins and GPIO
* Information about Device Tree files for the kernel
* The code references are for the VLP64 v1.0.x releases *(the older Linux-4.19 BSP)
* The code refences are for the RZ/G2H,M,N,E devices.
<br>
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.
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.


Line 17: Line 31:




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.
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 table below summarizes where the different actors in the boot process are '''typically''' stored and executed from.
 
{| class="wikitable"
!Item
!Stored into
!Executed out of
|-
|Boot ROM
|Internal SOC ROM
|XIP (eXecuted In Place)
|-
|BL2
|QSPI/eMMC boot part/SD card
|Internal SRAM
|-
|BL31-BL32
|QSPI/eMMC boot part/SD card
|DDR (secured by TrustZone)
|-
|BL33 (u-boot)
|QSPI/eMMC boot part/SD card
|DDR
|-
|Linux kernel
|eMMC/SD card
|DDR
|-
|GNU OS (rootfs)
|eMMC/SD card
|DDR
|}
The next step is to port the [https://github.com/renesas-rz/rz_linux-cip 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.
The next step is to port the [https://github.com/renesas-rz/rz_linux-cip 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.


Line 24: Line 66:


=Flash Writer=
=Flash Writer=
 
* [[RZ-G/RZ-G2_BSP_Porting_FlashWriter]]
==Cloning repository==
 
=== SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
git clone <nowiki>https://github.com/renesas-rz/rzg2_flash_writer</nowiki>
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, RZ/V2L ===
git clone <nowiki>https://github.com/renesas-rz/rzg2_flash_writer</nowiki>
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:'''<br>1. Make a copy of the template file '''ddr/lpddr4/my_boot_dram_config.c'''
<pre>
$ cp ddr/lpddr4/my_boot_dram_config.c  ddr/lpddr4/xyz_boot_dram_config.c
</pre>
2. Add your new file to the build system by editing the makefile '''ddr/lpddr4/ddr.mk'''
<pre>
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 <<<<<<<<<<
</pre>
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, RZ/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 [https://github.com/renesas-rz/rzg2_flash_writer 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:
<pre>
#define CYPRESS_MANUFACTURER_ID 0x01 /* Cypress */
#define WINBOND_MANUFACTURER_ID 0xEF /* Winbond */
#define MACRONIX_MANUFACTURER_ID 0xC2 /* Macronix */
#define MICRON_MANUFACTURER_ID 0x20 /* Micron */
</pre>
* Confirm if the Device ID for your flash devices is listed. If not, then add it.
<pre>
#define DEVICE_ID_S25FS128S 0x2018
</pre>
'''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'''
<pre>
case DEVICE_ID_S25FS512S:
PutStr("S25FS512S", 1);
gQspi_sa_size    = SA_256KB;
gQspi_end_addess = TOTAL_SIZE_64MB - 0x8000 - 1;
break;
</pre>
 
🎈 If you successfully added a new SPI Flash device, please let us know so we can update the code for everyone 🧑‍🤝‍🧑. You can [https://github.com/renesas-rz/rzg2_flash_writer/issues submit a new issue] on the github site, or send an email to renesas-rz@renesas.com. Thank you.
 
== Building and debugging ==
 
=== SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
Content: TBD
 
=== SoC: RZ/G2L, RZ/V2L ===
You can build Flash Writer by following the [https://github.com/renesas-rz/rzg2_flash_writer/tree/rz_g2l#4-how-to-build-the-rzg2l-flash-writer Readme], the only difference is that you have to use BOARD=CUSTOM (or the name you chose) as per [[RZ-G/RZ-G2 BSP Porting#SoC: RZ.2FG2L.2C RZ.2FV2L 2|these instructions]].
 
It is worth to note that in order to enable Flash Writer to program eMMC, it has to be built with a specific flag: EMMC=ENABLE.
 
You can also use Eclipse to build and debug Flash Writer using [[RZ-G/RZG openocd|OpenOCD]] as documented [[RZ-G/RZG2 Eclipse develop and debug#Building RZ.2FG2L Flash Writer|here]]. Obviously there is always the possibility to debug using the good old printf (PutStr function in Flash Writer).


= Arm Trusted Firmware =
= Arm Trusted Firmware =
 
* [[RZ-G/RZ-G2_BSP_Porting_ATF]]
== Cloning repository ==
 
=== SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
git clone <nowiki>https://github.com/renesas-rz/rzg_trusted-firmware-a/</nowiki>
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, RZ/V2L ===
git clone <nowiki>https://github.com/renesas-rz/rzg_trusted-firmware-a/</nowiki>
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, RZ/V2L ===
The DDR configuration files (''param_mc.c'' and ''param_swizzle.c)'' to be used with ATF are the [[RZ-G/RZ-G2 BSP Porting#SoC: RZ.2FG2L-V2L 2|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/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
Content: TBD
 
=== SoC: RZ/G2L, RZ/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.
<pre>
spi_multi_setup(SPI_MULTI_ADDR_WIDES_24, SPI_MULTI_DQ_WIDES_1_4_4, SPI_MULTI_DUMMY_10CYCLE)
</pre>
* 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.
<pre>
/* 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);
</pre>
 
===== 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/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
Content: TBD
 
It is worth to note that in order to build ATF with eMMC boot support, it has to be built with the flag RZG_SA6_TYPE=1.
 
=== SoC: RZ/G2L, RZ/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
Please note that, compared to RZ/G2E-N-M-H, for RZ/G2L and RZ/V2L there is no need to add any specific flag to enable eMMC boot in ATF.
 
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 [[RZ-G/RZ-G2 BSP Porting#SoC: RZ.2FG2L-V2L 10|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
ATF BL2 is what you more often might need to debug, since this is the part that includes most of the system specific options. Obviously it is possible to use the various log options (INFO, NOTICE, DEBUG, etc), however especially during the first stages or if something is difficult to catch, it might be just more convenient to use a JTAG debugger and [[RZ-G/RZG openocd|OpenOCD]]. In this way you do not need to reflash the bootloaders every time since the new image is just loaded in the internal RAM directly. You can refer to [[RZ-G/RZG2 Eclipse develop and debug#Debugging Arm Trusted Firmware using OpenOCD - Dedicated plugin|this section]], that shows how to setup the OpenOCD Eclipse plugin to debug BL2.


= u-boot =
= u-boot =
 
* [[RZ-G/RZ-G2_BSP_Porting_uboot]]
== Cloning repository ==
 
=== SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
git clone <nowiki>https://github.com/renesas-rz/renesas-u-boot-cip</nowiki>
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, RZ/V2L ===
git clone <nowiki>https://github.com/renesas-rz/renesas-u-boot-cip</nowiki>
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
 
== 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
[[File:U-boot menuconfig.png|frameless|900x900px]]
 
You can search by typing "/" (slash). Firstly you need to change the default fdt file (search DEFAULT_FDT_FILE) to reflect the board name:
 
[[File:u-boot fdt.png|frameless|900x900px]]
 
And select your custom board as target (search MY_CUSTOM_BOARD):
 
[[File:u-boot board selection.png|frameless|900x900px]]
 
Select also my_custom_board as default device tree (search DEFAULT_DEVICE_TREE):
 
[[File:u-boot default device tree.png|frameless|900x900px]]
 
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
<code>CONFIG_SYS_MMC_ENV_DEV</code>: It specifies which MMC device has to be used to store the environment variables;
 
<code>CONFIG_SYS_MMC_ENV_PART</code>: which MMC area (0=user, 1=boot 1, 2=boot 2);
 
<code>CONFIG_ENV_SIZE</code>: as the name suggests, size;
 
<code>CONFIG_ENV_OFFSET</code>: 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.
 
[[File:U-boot menuconfig env variables.png|frameless|600x600px]]
 
== Device tree ==
 
=== 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
<code>CONFIG_EXTRA_ENV_SETTINGS</code> and <code>CONFIG_BOOTCOMMAND</code> 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 [[RZ-G/RZ-G2 BSP Porting#SoC: RZ.2FG2L-V2L 7|this section]].


= Linux Kernel =
= Linux Kernel =
* [[RZ-G/RZ-G2_BSP_Porting_kernel]]


== Cloning repository ==
=Yocto=
 
* [[RZ-G/RZ-G2_BSP_Porting_Yocto]]
=== SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
Content: TBD
 
=== SoC: RZ/G2L, RZ/V2L ===
Content: TBD
== Device tree ==
=== SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H===
Content: TBD
 
=== SoC: RZ/G2L, RZ/V2L ===
Content: TBD
== Source code modification ==
=== SoC: RZ/G2E, RZ/G2N, RZ/G2M, RZ/G2H ===
Content: TBD
 
=== SoC: RZ/G2L, RZ/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 [https://github.com/seebe/rzg_stuff/tree/master/build_scripts_new 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 [https://github.com/seebe/rzg_stuff/blob/master/build_scripts_new/Toolchain%20Installs.txt 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 [https://www.renesas.com/us/en/products/microcontrollers-microprocessors/rz-cortex-a-mpus/rzg-linux-platform/rzg-marketplace/verified-linux-package/rzg2-mlp-eva 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, RZ/V2L ===
Content:TBD


== SD Card Speed ==
= Ubuntu =


=== SoC: All ===
* [[RZ-G/RZ-G2 BSP_Porting_Ubuntu]]
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.
<pre>
max-frequency = <50000000>
</pre>


=Yocto=
= OpenWRT=
 
* [[RZ-G/RZ-G2 BSP_Porting_OpenWRT]]
=== SoC: All ===


= Debian =
* [[RZ-G/RZ-G2 BSP Porting Debian]]
=Memory Map=
=Memory Map=
*This section explains how DDR Memory is divided and configured. Since all software components (boot loaders and Linux) needs to have the same settings, we will discuss all the software components in this section.
* This section explains how DDR Memory is divided and configured.
* [[RZ-G/RZ-G2_BSP_MemoryMap]]


==Description of Areas==
= Changing Console Port =
You can make use of the following changes to change console port from SCIF0 to SCIF2 in RZ/G2L-LC and RZ/V2L (Not applicable for RZ/G2UL). Please note that it '''NOT RECOMMENDED''' by Renesas to do so and is described here only for experimental purpose.


'''Secure Area:'''<br>
* To redirect the output from SCIF0 to SCIF2, we need to change the ''stdout'' to reflect the respective console output in the ATF, u-boot and kernel. The output is obtained on PMOD1 through a UART module.
* In order to use Trust Zone and OP-TEE in your system, the secure area must be hidden from Linux. This means early in boot in the ARM Trusted Firmware code (BL2), the memory sections are configure so that non-secure code (u-boot and kernel) cannot access them.
* We start by modifying the ATF:
* By default, the BSP allocates 128MB of space at the beginning of DDR Memory. That is why in the Device Tree settings for u-boot and kernel, the starting memory address is not the begging of physical DDR space because we are trying 'hide' this from Linux. In fact, even if the CPU tries to access this area, a hardware fault will occur.
** The console driver is initialized with SCIF2 base address and the corresponding pin functions are defined enable the output through SCIF2.
 
** The clock/reset signals are applied for SCIF2.
'''CR7 and CM33 Area:'''<br>
* Next we move onto u-boot where we redefine the ''stdout'' to to output on SCIF2 console.
* The DDR area for the the sub-cores should be mapped below the memory allocated for the Linux kernel.
* Finally in the kernel:
* The DDR location can be in Secure or non-Secure area.
** We once again redefine the ''stdout.''
* The default non-secure physical DDR address for the CR7 is 0x40040000
** Enable the clock for SCIF2, so it is not put into standby mode.
* The default non-secure physical DDR address for the CM33 is 0x40010000
 
'''H.264 Encode/Decode Area:'''<br>
* The H.264 video codec drivers require dedicated memory. This is allocated in the "mmp_reserved: linux, multimedia" area of the kernel Device Tree.
* The size of this area depends on the resolution of the images being encoded and decoded.
 
'''LCD Frame Buffer area'''<br>
* The LCD Frame buffer require dedicated memory. This is allocated in the "linux,cma" area of the kernel Device Tree.
* The size of this area depends on the resolution of LCD.
 
''' DDR Restricted Area (beginning of DDR)'''
* The first 64 bytes of DDR Address space (0x40000000) are restricted from being used.
* The reason is that the DDR3/DDR4 controller uses these address locations.
* Please do not allocate or use the beginning of the DDR address area.
* Please refer to the SoC Hardware Manuals for more details.


{| class="mw-collapsible mw-collapsed wikitable"
{| class="mw-collapsible mw-collapsed wikitable"
| Default RZ/G2L Memory Map in the BSP &emsp; &emsp;
|RZ/G2L: Changing Console Port from SCIF0 to SCIF2 &nbsp; &emsp; &emsp;
|-
|-
|
|'''Trusted Firmware-A'''
<pre>
┌───────────────────────────────────────┐0x40000000
│  unused (DDR controller)            │
├───────────────────────────────────────┤0x40010000
│  CM33                                │
├───────────────────────────────────────┤0x43F00000
│  BL31 Secure Monitor (2MB)          │
├───────────────────────────────────────┤0x44100000
│  BL32 (OP-TEE)  (61MB)              │
├───────────────────────────────────────┤0x47E00000
│  unused                              │
├───────────────────────────────────────┤0x48000000
│  BL33 (u-boot) and Linux (1.99GB)    │
└───────────────────────────────────────┘0x80000000
</pre>
|}


 
File: <font color="blue">plat/renesas/rz/common/include/rzg2l_def.h</font>
==How to modify ARM Trusted Firmware==
* This section explains how to modify the code for ARM Trusted Firmware.
* Trusted Firmware (BL31) and OP-TEE should reside in the Secure Area. The will allow HW protection from non-secure code such as Linux.
* Configure the settings in file '''plat/renesas/rz/common/include/plat_tzc_def.h'''
 
'''Start Address and size of Trusted Firmware (BL31):'''
<pre>
/* Trusted Firmware(BL31) secure DRAM 0x43F00000 - 0x440FFFFF */
#define PLAT_FW_TZC_PROT_DRAM1_BASE (0x43F00000)
#define PLAT_FW_TZC_PROT_DRAM1_SIZE (0x00200000)
</pre>
* Configure the settings in file '''plat/renesas/rz/common/include/platform_def.h'''
<pre>
<pre>
/*******************************************************************************
  #define RZG2L_SCIF0_BASE            (0x1004B800)
* BL31 specific defines.
+#define RZG2L_SCIF2_BASE            (0x1004C000)
  ******************************************************************************/
#define BL31_BASE (0x44000000)
#define BL31_LIMIT (0x44040000)
</pre>
</pre>


'''Start Address and size of OP-TEE (BL32):'''
File: <font color="blue">plat/renesas/rz/common/bl2_plat_setup.c</font>
<pre>
/* OP-TEE secure DRAM 0x44100000 - 0x47DFFFFF */
#define PLAT_TEE_TZC_PROT_DRAM1_BASE (0x44100000)
#define PLAT_TEE_TZC_PROT_DRAM1_SIZE (0x03D00000)
</pre>
<pre>
<pre>
/*******************************************************************************
initialize console driver */
* BL32 specific defines.
ret = console_rzg2l_register(
******************************************************************************/
- RZG2L_SCIF0_BASE,
#ifndef SPD_none
+ RZG2L_SCIF2_BASE,
#define BL32_BASE (0x44100000)
RZG2L_UART_INCK_HZ,
#define BL32_LIMIT (BL32_BASE + 0x100000)
RZG2L_UART_BARDRATE,
#endif
&rzg2l_bl31_console);
</pre>
</pre>


'''Remove OP-TEE Area (optional)'''
File: <font color="blue">plat/renesas/rz/common/bl31_plat_setup.c</font>
* If you will not be using OP-TEE at all, you can comment out the code that configures that area in file plat_security.c.
<pre>
<pre>
diff --git a/plat/renesas/rz/common/plat_security.c b/plat/renesas/rz/common/plat_security.c
initialize console driver */
index 4e9c96f81..35a4910c0 100755
ret = console_rzg2l_register(
--- a/plat/renesas/rz/common/plat_security.c
- RZG2L_SCIF0_BASE,
+++ b/plat/renesas/rz/common/plat_security.c
+ RZG2L_SCIF2_BASE,
@@ -115,8 +115,10 @@ static void bl2_security_setup(void)
RZG2L_UART_INCK_HZ,
    const arm_tzc_regions_info_t ddr_tzc_regions[] = {
RZG2L_UART_BARDRATE,
        {PLAT_FW_TZC_PROT_DRAM1_BASE, PLAT_FW_TZC_PROT_DRAM1_END,
&rzg2l_bl31_console);
            TZC_REGION_S_RDWR, PLAT_TZC_REGION_ACCESS_S_UNPRIV},
+#if 0
        {PLAT_TEE_TZC_PROT_DRAM1_BASE, PLAT_TEE_TZC_PROT_DRAM1_END,
            TZC_REGION_S_RDWR,  PLAT_TZC_REGION_ACCESS_S_UNPRIV},
+#endif
        {}
    };
</pre>
</pre>


==How to modify u-boot==
File: <font color="blue">plat/renesas/rz/common/drivers/cpg.c</font>
* This section explains how to modify the code for u-boot.
* U-boot uses a Device Tree file to configure the memory size. There is a 'memory' node that configures the start address and size of DDR memory to use.
* For example:
<pre>
<pre>
memory@48000000 {
{ /* SCIF */
device_type = "memory";
(uintptr_t)CPG_CLKON_SCIF,
/* first 128MB is reserved for secure area. */
  (uintptr_t)CPG_CLKMON_SCIF,
reg = <0 0x48000000 0 0x78000000>;
- 0x001f0001,
  };
+ 0x001f0004,
</pre>
CPG_T_CLK
* ⚠ The 'memory' node in the Device Tree of u-boot is used for u-boot and is '''also used for the kernel Device Tree'''. When u-boot boots the kernel, it '''automatically overwrites''' the value in the kernel's Device Tree. This means that what you put in the kernel memory node in the kernel Device Tree will have no effect.
},
* There is also a define '''DRAM_RSV_SIZE''' that needs to be modified. This will be in the config file for your board. Set it to the size of your secure area that will be hidden from u-boot and Linux.
* For example, for the RZ/G2L SMARC board, that is file '''include/configs/smarc-rzg2l.h'''
<pre>
#define DRAM_RSV_SIZE 0x80000000
</pre>
</pre>


==How to modify kernel==
File: <font color="blue">plat/renesas/rz/common/include/pfc_regs.h</font>
* This section explains how to modify the code for the Linux.
* You should only need to modify the '''Device Tree''' files
* ⚠ Note that modifying '''memory node''' in the kernel device tree has '''no effect'''. The reason is that before boot, u-boot will '''overwrite''' the values in the kernel device tree. This means it is important that you set the device tree in u-boot to the setting you want the kernel to have. However, the other settings such as "linux,cma" and "linux,multimedia" are only set in the kernel device tree.
'''memory Node'''
* Defines the total memory for the Linux System
* Should match what you put in u-boot Device Tree
* Has no effect (overwritten by u-boot before boot)
<pre>
<pre>
memory@48000000 {
-#define PFC_MUX_TBL_NUM (4)
device_type = "memory";
+#define PFC_MUX_TBL_NUM (5)
/* first 128MB is reserved for secure area. */
reg = <0x0 0x48000000 0x0 0x78000000>;
};
</pre>
</pre>


'''linux,cma Node'''
File: <font color="blue">plat/renesas/rz/common/drivers/pfc.c</font>
* CMA stands for "Contiguous Memory Allocator"
* Allow allocation of big, physically-contiguous memory blocks used for things like DMA transfers or LCD Frame Buffer.
* Depending on the size (resolution) of your LCD, you will increase or decrease this size.
* If you are transferring a lot of data over a network (Ethernet) or USB, you might need to includes this area to have enough buffer area.
<pre>
<pre>
reserved-memory {
{ PFC_OFF, (uintptr_t)NULL,      0 } /* IEN */
#address-cells = <2>;
+},
#size-cells = <2>;
+/* P40(scif2) */
ranges;
+{
 
+ { PFC_ON,  (uintptr_t)PFC_PMC40,  0x1F }, /* PMC */
reserved: linux,cma@58000000 {
+ { PFC_ON,  (uintptr_t)PFC_PFC40,  0x00011111 }, /* PFC */
compatible = "shared-dma-pool";
+ { PFC_OFF, (uintptr_t)PFC_IOLH40, 0x0000000101010101 }, /* IOLH */
linux,cma-default;
+ { PFC_OFF, (uintptr_t)PFC_PUPD40, 0x0000000000000000 }, /* PUPD */
reusable;
+ { PFC_OFF, (uintptr_t)PFC_SR40,  0x0000000101010101 }, /* SR */
reg = <0x0 0x58000000 0x0 0x10000000>;
+ { PFC_OFF, (uintptr_t)NULL,      0 } /* IEN */
};
}
};
#endif
};
</pre>
</pre>


'''linux,multimedia Node'''
'''u-boot'''
* This area is used for H.264 encode or decode.
* Depending on the resolution of your frames, you many need to increase or decrease this area.
<pre>
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;


mmp_reserved: linux,multimedia {
File: <font color="blue">arch/arm/dts/smarc-rzg2l.dts</font>
compatible = "shared-dma-pool";
reusable;
reg = <0x00000000 0x68000000 0x0 0x8000000>;
};
};
</pre>
 
==Examples==
'''Reduce reserved area for RZ/G2L SMARC board'''
* If you are not evaluating security (OP-TEE) or sub-core (CM33), you can reduce the reserved area from 128MB to 2MB.
* The Linux kernel must be aligned on a 2MB address boundary, so that is our minimum reserved area size.
* Move BL31 0x43F00000 >> 0x40001000
* Reduce BL31 size 0x200000 >> 0xFE000
* Move BL32 (OP-TEE) 0x44100000 >> 0x400FF000
* Reduce BL32 (OP-TEE) size 0x100000 >> 0x1000  (too small to be used)
* Move u-boot and kernel 0x48000000 >> 40200000 (skip beginning of 2MB of DDR) and increase size by 126MB
* Expand below to show what files need to be modified.
{| class="mw-collapsible mw-collapsed wikitable"
| RZ/G2L: Reduce reserved area in Linux from 128MB to 2MB &nbsp; &emsp; &emsp;
|-
|
'''Trusted Firmware-A'''
 
File: <font color=blue>plat/renesas/rz/common/include/plat_tzc_def.h</font>
<pre>
<pre>
-/* Trusted Firmware(BL31) secure DRAM 0x43F00000 - 0x440FFFFF */
aliases {
-#define PLAT_FW_TZC_PROT_DRAM1_BASE            (0x43F00000)
serial0 = &scif0;
-#define PLAT_FW_TZC_PROT_DRAM1_SIZE            (0x00200000)
+ serial1 = &scif2;
+/* Trusted Firmware(BL31) secure DRAM 0x40001000 - 0x400FEFFF */
spi0 = &spibsc;
+#define PLAT_FW_TZC_PROT_DRAM1_BASE            (0x40001000)
};
+#define PLAT_FW_TZC_PROT_DRAM1_SIZE            (0x000FE000)
</pre>
<pre>
-/* OP-TEE secure DRAM 0x44100000 - 0x47DFFFFF */
-#define PLAT_TEE_TZC_PROT_DRAM1_BASE  (0x44100000)
-#define PLAT_TEE_TZC_PROT_DRAM1_SIZE  (0x03D00000)
+/* OP-TEE secure DRAM 0x400FF000 - 0x400FFFFF */
+#define PLAT_TEE_TZC_PROT_DRAM1_BASE  (0x400FF000)
+#define PLAT_TEE_TZC_PROT_DRAM1_SIZE  (0x00001000)
</pre>
</pre>


File: <font color=blue>plat/renesas/rz/common/include/platform_def.h</font>
<pre>
<pre>
-#define BL31_BASE                              (0x44000000)
chosen {
-#define BL31_LIMIT                            (0x44040000)
- stdout-path = "serial0:115200n8";
+#define BL31_BASE                              (0x40001000)
+ stdout-path = "serial1:115200n8";
+#define BL31_LIMIT                            (BL31_BASE + 0xFE000)
};
</pre>
<pre>
-#define BL32_BASE                              (0x44100000)
-#define BL32_LIMIT                            (BL32_BASE + 0x100000)
+#define BL32_BASE                              (0x400FF000)
+#define BL32_LIMIT                            (BL32_BASE + 0x1000)
</pre>
</pre>


'''u-boot'''
'''kernel'''


File: <font color=blue>include/configs/smarc-rzg2l.h</font>
File: <font color="blue"> arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi</font>
<pre>
<pre>
-#define DRAM_RSV_SIZE 0x08000000
/* comment the #define statement to disable SCIF2 (SER0) on PMOD1 (CN7) */
+#define DRAM_RSV_SIZE 0x00200000
-//#define PMOD1_SER0  1
+#define PMOD1_SER0    1
</pre>
</pre>
File: <font color=blue>arch/arm/dts/smarc-rzg2l.dts</font>
 
File: <font color="blue">arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi</font>
<pre>
<pre>
         memory@40200000 {
         chosen {
                device_type = "memory";
-              stdout-path = "serial0:115200n8";
                /* first 2MB is reserved */
+              stdout-path = "serial1:115200n8";
                reg = <0x0 0x40200000 0x0 0x7FE00000>;
+              bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
         };
         };
</pre>
</pre>


'''kernel'''
File: <font color="blue">drivers/clk/renesas/r9a07g044-cpg.c</font>
 
* Note that this change has no effect because u-boot overwrites it anyway.
File: <font color=blue>arch/arm64/boot/dts/renesas/r9a07g044l2-smarc.dts</font>
<pre>
<pre>
         memory@40200000 {
static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
                device_type = "memory";
         MOD_CLK_BASE + R9A07G044_IA55_PCLK,
                /* first 2MB is reserved */
        MOD_CLK_BASE + R9A07G044_IA55_CLK,
                reg = <0x0 0x40200000 0x0 0x7FE00000>;
        MOD_CLK_BASE + R9A07G044_DMAC_ACLK,
        };
+      MOD_CLK_BASE + R9A07G044_SCIF2_CLK_PCK,
};
</pre>
</pre>
|}


'''New Boot Command:'''
=Github Repositories=
* Remember that you have to load the kernel and device tree to a different location in DDR
*These are the repositories where Renesas publishes the RZ code to.
* Load your kernel Image to 0x40280000
**https://github.com/renesas-rz/rz_linux-cip
* Load your Device Tree Blob (dtb) to 0x40200000
**https://github.com/renesas-rz/renesas-u-boot-cip
* Use new addresses for booti command
**https://github.com/renesas-rz/rzg2_flash_writer
<pre>
**https://github.com/renesas-rz/rzg_trusted-firmware-a
=> set sd_boot1 'mmc dev 1 ; fatload mmc 1:1 0x40280000 Image ; fatload mmc 1:1 0x40200000 /r9a07g044l2-smarc.dtb'
*Information on each '''branch''' is located in the wiki section
=> set sd_boot2 'setenv bootargs root=/dev/mmcblk1p2 rootwait ; booti 0x40280000 - 0x40200000'
**https://github.com/renesas-rz/rz_linux-cip/wiki
=> saveenv
**https://github.com/renesas-rz/renesas-u-boot-cip/wiki
</pre>
**https://github.com/renesas-rz/rzg2_flash_writer/wiki
**https://github.com/renesas-rz/rzg_trusted-firmware-a/wiki
 
=How to build=
The easiest and recommended way to build is by using [https://github.com/renesas-rz/rzg2_bsp_scripts/tree/master/build_scripts these scripts]. Otherwise you can install the toolchain as per [https://github.com/renesas-rz/rzg2_bsp_scripts/blob/master/build_scripts/Toolchain%20Installs.txt these instructions] and build manually following the instructions provided case by case.


|}
Usually you also have to make sure that the path is correct and the triplet / quadruplet is set correctly, as well as the architecture. For example, a command similar to the following must be given before any <code>make</code> attempt:
PATH=/opt/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf/bin:$PATH ; export CROSS_COMPILE=aarch64-none-elf-; export ARCH=arm64

Latest revision as of 17:53, 7 February 2024


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

Overview

There is s a RZ/G2 Group Linux BSP Porting Guide document posted on Renesas.com.

This document contains information such as:

  • How to add a new build configuration for a new board to a Yocto
  • How to add a new build configuration for a new board to a u-boot
  • Information about configuring pins and GPIO
  • Information about Device Tree files for the kernel
  • The code references are for the VLP64 v1.0.x releases *(the older Linux-4.19 BSP)
  • The code refences are for the RZ/G2H,M,N,E devices.


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 may 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 table below summarizes where the different actors in the boot process are typically stored and executed from.

Item Stored into Executed out of
Boot ROM Internal SOC ROM XIP (eXecuted In Place)
BL2 QSPI/eMMC boot part/SD card Internal SRAM
BL31-BL32 QSPI/eMMC boot part/SD card DDR (secured by TrustZone)
BL33 (u-boot) QSPI/eMMC boot part/SD card DDR
Linux kernel eMMC/SD card DDR
GNU OS (rootfs) eMMC/SD card DDR

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 bobs you need to run your custom application.

Flash Writer

Arm Trusted Firmware

u-boot

Linux Kernel

Yocto

Ubuntu

OpenWRT

Debian

Memory Map

Changing Console Port

You can make use of the following changes to change console port from SCIF0 to SCIF2 in RZ/G2L-LC and RZ/V2L (Not applicable for RZ/G2UL). Please note that it NOT RECOMMENDED by Renesas to do so and is described here only for experimental purpose.

  • To redirect the output from SCIF0 to SCIF2, we need to change the stdout to reflect the respective console output in the ATF, u-boot and kernel. The output is obtained on PMOD1 through a UART module.
  • We start by modifying the ATF:
    • The console driver is initialized with SCIF2 base address and the corresponding pin functions are defined enable the output through SCIF2.
    • The clock/reset signals are applied for SCIF2.
  • Next we move onto u-boot where we redefine the stdout to to output on SCIF2 console.
  • Finally in the kernel:
    • We once again redefine the stdout.
    • Enable the clock for SCIF2, so it is not put into standby mode.
RZ/G2L: Changing Console Port from SCIF0 to SCIF2      
Trusted Firmware-A

File: plat/renesas/rz/common/include/rzg2l_def.h

 #define RZG2L_SCIF0_BASE            (0x1004B800)
+#define RZG2L_SCIF2_BASE            (0x1004C000)

File: plat/renesas/rz/common/bl2_plat_setup.c

initialize console driver */
ret = console_rzg2l_register(
-	RZG2L_SCIF0_BASE,
+	RZG2L_SCIF2_BASE,
 	RZG2L_UART_INCK_HZ,
 	RZG2L_UART_BARDRATE,
 	&rzg2l_bl31_console);

File: plat/renesas/rz/common/bl31_plat_setup.c

initialize console driver */
ret = console_rzg2l_register(
-	RZG2L_SCIF0_BASE,
+	RZG2L_SCIF2_BASE,
 	RZG2L_UART_INCK_HZ,
 	RZG2L_UART_BARDRATE,
 	&rzg2l_bl31_console);

File: plat/renesas/rz/common/drivers/cpg.c

{	/* SCIF */
 	(uintptr_t)CPG_CLKON_SCIF,
 	(uintptr_t)CPG_CLKMON_SCIF,
-	0x001f0001,
+	0x001f0004,
 	CPG_T_CLK
},

File: plat/renesas/rz/common/include/pfc_regs.h

-#define PFC_MUX_TBL_NUM		(4)
+#define PFC_MUX_TBL_NUM		(5)

File: plat/renesas/rz/common/drivers/pfc.c

	{ PFC_OFF, (uintptr_t)NULL,       0 }			/* IEN */
+},
+/* P40(scif2) */
+{
+	{ PFC_ON,  (uintptr_t)PFC_PMC40,  0x1F },		/* PMC */
+	{ PFC_ON,  (uintptr_t)PFC_PFC40,  0x00011111 },		/* PFC */
+	{ PFC_OFF, (uintptr_t)PFC_IOLH40, 0x0000000101010101 }, /* IOLH */
+	{ PFC_OFF, (uintptr_t)PFC_PUPD40, 0x0000000000000000 },	/* PUPD */
+	{ PFC_OFF, (uintptr_t)PFC_SR40,   0x0000000101010101 },	/* SR */
+	{ PFC_OFF, (uintptr_t)NULL,       0 }			/* IEN */
 }
 #endif
 };

u-boot

File: arch/arm/dts/smarc-rzg2l.dts

 aliases {
 	serial0 = &scif0;
+	serial1 = &scif2;
 	spi0 = &spibsc;
 };
 chosen {
-	stdout-path = "serial0:115200n8";
+	stdout-path = "serial1:115200n8";
 };

kernel

File: arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi

 /* comment the #define statement to disable SCIF2 (SER0) on PMOD1 (CN7) */
-//#define PMOD1_SER0   1
+#define PMOD1_SER0     1

File: arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi

        chosen {
-               stdout-path = "serial0:115200n8";
+               stdout-path = "serial1:115200n8";
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
        };

File: drivers/clk/renesas/r9a07g044-cpg.c

 static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
        MOD_CLK_BASE + R9A07G044_IA55_PCLK,
        MOD_CLK_BASE + R9A07G044_IA55_CLK,
        MOD_CLK_BASE + R9A07G044_DMAC_ACLK,
+       MOD_CLK_BASE + R9A07G044_SCIF2_CLK_PCK,
 };

Github Repositories

How to build

The easiest and recommended way to build is by using these scripts. Otherwise you can install the toolchain as per these instructions and build manually following the instructions provided case by case.

Usually you also have to make sure that the path is correct and the triplet / quadruplet is set correctly, as well as the architecture. For example, a command similar to the following must be given before any make attempt:

PATH=/opt/arm/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf/bin:$PATH ; export CROSS_COMPILE=aarch64-none-elf-; export ARCH=arm64