You can enable and disable CPU cores by writing to a sysfs value.
This is helpful for when you want to experiment with the performance of your application if you were to use a processor with less CPU cores.
For example, this command will disable the 2nd core.
$ echo 0 > /sys/devices/system/cpu/cpu1/online
More detailed information can be found here: https://www.cyberciti.biz/faq/debian-rhel-centos-redhat-suse-hotplug-cpu
About power consumption in RZ/G2 series, we have some supported features to save power cost in default environment:
Therefore, select proper method will be based on user's purpose. Here are my examples:
Here are some commands to check frequency value and frequency governor in linux:
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_governors
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor (performance/userspace/schedutil/...)
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
echo 15000 > /sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq
The easiest way to access the PMIC registers from command line would would be to use i2ctools. Add the following line to your local.conf.
IMAGE_INSTALL_append = " i2c-tools"
However the PMICs are connected to a I2C (IIC for PMIC or I2C_DVFS) that is not enabled in the default kernel device tree. For the HiHope boards, you can edit the file arch/arm64/boot/dts/renesas/hihope-common.dtsi
and add the following lines at the very bottom of the file.
&i2c_dvfs { status = "okay"; };
Once booted in Linux, the corresponding device should be /dev/i2c-7
You can query the connected slaves by giving the following command:
i2cdetect -y -r 7
that on the RZ/G2E board produces the output:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e 1f 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
So two slaves, at address 0x1e and 0x1f. Finally you can read registers by simply using the i2cget command, for example:
i2cget -y 7 0x1e 0x1 0x02 i2cget -y 7 0x1e 0x16 0x00 i2cget -y 7 0x1e 0x17 0xc4
If you don't want (or can't) update the device tree blob, you could use u-boot to do it temporarily. The procedure below is valid for RZ/G2M but it works also with RZ/G2E-N-H by simply modifying the device tree blob and/or kernel image names.
1) Interrupt the normal kernel boot
2) Once in u-boot, enter the follow commands (after each RESET)
=> fatload mmc 0:1 0x48080000 Image; fatload mmc 0:1 0x48000000 Image-r8a774a1-hihope-rzg2m-ex.dtb; => fdt addr 0x48000000 => fdt set /soc/i2c@e60b0000 status "okay"
and finally boot the kernel:
=> booti 0x48080000 - 0x48000000
In the kernel, there is no make target to make a uImage for the 64-bit ARM architecture like there is for 32-bit ARM. However, you can manually make one from the file Image.gz that is created by the kernel build system by using the following command on your host machine.
$ cd arch/arm64/boot $ mkimage -A arm64 -O linux -T kernel -C gzip -a 0x48080000 -e 0x48080000 -n "Linux Kernel Image" -d Image.gz uImage
Below is an example of booting this image on a RZ/G2 HiHiope board from u-boot.
=> fatload mmc 0:1 0x88000000 uImage => fatload mmc 0:1 0x48000000 Image-r8a774e1-hihope-rzg2h-ex.dtb => bootm 0x88000000 - 0x48000000
The Verified Linux Package (VLP64 v1.x.y) includes the CIP kernel (v4.19.x) and until 2022 it is was the only official kernel to have all the features in. Since 2023 VLP3 includes CIP kernel 5.10. However it is possible to build a working kernel directly from mainline. The kernel built in this way does not provide most of the multimedia functionalities (e.g. GPU, codec, etc).
A recent Linaro toolchain is needed to build the kernel. The instructions below are for v5.10.x, newer kernel versions can be built as well in a similar way.
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
git checkout tags/v5.10.42
or anyway the latest minor revision including bug fixes.
Copy Renesas default kernel build into .out/.config:
cp arch/arm64/configs/renesas_defconfig .out/.config
or, if not present, get from the repository:
wget -O .out/.config https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/plain/arch/arm64/configs/renesas_defconfig
If you want to be able to build modules:
echo CONFIG_MODULES=y >> .out/.config
echo CONFIG_MODULE_UNLOAD=y >> .out/.config
Run kernel configuration:
make O=.out menuconfig
Exit and save. Then launch the build:
make O=.out all -j$(nproc)
Since linux-4.8 the GPIO sysfs interface is deprecated. User space should use the character device instead. The libgpiod library encapsulates the ioctl calls and data structures behind a straightforward API.
Also, the kernel source code contains a GPIO utility for user space. Please see directory tools/gpio/ in the kernel source code.
1) lsgpio – example on how to list the GPIO lines on a system2) gpio-event-mon – monitor GPIO line events from userspace3) gpio-hammer - example to shake GPIO lines on a system
RZ/G2M/H/N/E Numbering
GPIO chip: gpiochip6, "e6055400.gpio", 18 GPIO lines line 0: unnamed unused .... .... line 17: unnamed unused GPIO chip: gpiochip5, "e6055000.gpio", 20 GPIO lines line 0: unnamed unused .... .... line 19: unnamed unused [output] GPIO chip: gpiochip4, "e6054000.gpio", 11 GPIO lines line 0: unnamed unused .... .... line 10: unnamed unused GPIO chip: gpiochip3, "e6053000.gpio", 16 GPIO lines line 0: unnamed unused .... .... line 15: unnamed unused GPIO chip: gpiochip2, "e6052000.gpio", 26 GPIO lines line 0: unnamed unused .... .... line 25: unnamed "wlan-en-regulator" [kernel output] GPIO chip: gpiochip1, "e6051000.gpio", 23 GPIO lines line 0: unnamed "interrupt" [kernel] .... .... line 22: unnamed unused GPIO chip: gpiochip0, "e6050000.gpio", 18 GPIO lines line 0: unnamed unused .... .... line 17: unnamed unused
RZ/G2L Numbering
GPIO chip: gpiochip0, "11030000.pin-controller", 392 GPIO lines line 0: unnamed unused .... .... line 390: unnamed unused line 391: unnamed unused
$ source /opt/poky/2.4.3/environment-setup-aarch64-poky-linux $ make
IMAGE_INSTALL_append = “ libgpiod libgpiod-tools”
Command Line Tools:
1) gpiodetect: To find out which GPIO banks and how many GPIO lines are available on the hardware
root@ek874:~# gpiodetect gpiochip6 [e6055400.gpio] (18 lines) gpiochip5 [e6055000.gpio] (20 lines) gpiochip4 [e6054000.gpio] (11 lines) gpiochip3 [e6053000.gpio] (16 lines) gpiochip2 [e6052000.gpio] (26 lines) gpiochip1 [e6051000.gpio] (23 lines) gpiochip0 [e6050000.gpio] (18 lines)
2) gpioinfo: List all lines of specified gpiochips, their names, direction, active state and additional flags
gpiochip1 - 23 lines: line 0: unnamed "interrupt" input active-high [kernel] line 1: unnamed "interrupt" input active-high [kernel] .... .... line 22: unnamed unused input active-high gpiochip0 - 18 lines: line 0: unnamed unused input active-high line 1: unnamed unused input active-high .... .... line 17: unnamed unused input active-high
3) gpiofind: Find the gpiochip name and line offset given the line name. For RZ/G, we do not have pin name export in driver, so we can not use pin name to find the pin line.
4) gpioset: Set the values of specified GPIO lines. gpioset expects the bank, gpiochip, GPIO line and the value to be set, 1 for HIGH and 0 for LOW active-high standard
Examples:
gpioset gpiochip5 3=1 ### To set the line 3 of gpiochip5 to 1 (but it will also immediately go back to 0) gpioset --mode=signal --background gpiochip5 19=1 ### Set the pin to 1, but continue to running in the background so the pin will stay 1 gpioset --mode=time –-sec=1 gpiochip0 328=0 ### toggle the pin for 1 sec gpioset --mode=wait gpiochip0 328=0 ### toggle the pin and wait the user to press ENTER
5) gpioget: Read values of specified GPIO lines
root@ek874:~# gpioget gpiochip6 10
$ source /opt/poky/2.4.3/environment-setup-aarch64-poky-linux $ make
To show the current usage of all GPIOs in the system, enter this:
$ cat /sys/kernel/debug/gpio
RZ/G2M/H/N/E Numbering for sysfs
RZ/G2E RZ/G2M/N/H GPIO Bank Address GPIO Bank Address GPIO 0 494 GPIO 0 496 GPIO 1 471 GPIO 1 467 GPIO 2 445 GPIO 2 452 GPIO 3 429 GPIO 3 436 GPIO 4 418 GPIO 4 418 GPIO 5 398 GPIO 5 392 GPIO 6 380 GPIO 6 360 GPIO 7 356
=> setenv gpioLED_1=fatload mmc 0:1 0x48080000 Image-ek874.bin; fatload mmc 0:1 0x48000000 Image-r8a774c0-ek874-revc-mipi-2.1.dtb => setenv gpioLED_2=fdt addr 0x48000000 ; fdt rm /leds => setenv gpioLED_3=booti 0x48080000 - 0x48000000 => setenv gpioLED_boot=run gpioLED_1 gpioLED_2 gpioLED_3 => setenv ** Then run the command to boot => run gpioLED_boot
root@ek874:~# echo 417 > /sys/class/gpio/export # request gpio417 root@ek874:~# echo out > /sys/class/gpio/gpio417/direction # set gpio417 (GP5_19) output root@ek874:~# echo 1 > /sys/class/gpio/gpio417/value # turn ON LED0 root@ek874:~# cat /sys/class/gpio/gpio417/value 1 root@ek874:~# echo 0 > /sys/class/gpio/gpio417/value # turn OFF LED0 root@ek874:~# cat /sys/class/gpio/gpio417/value 0
RZ/G2L Pin Numbering for sysfs
root@smarc-rzg2l:~# echo 460 > /sys/class/gpio/export root@smarc-rzg2l:~# echo in > /sys/class/gpio/gpio460/direction root@smarc-rzg2l:~# cat /sys/class/gpio/gpio460/value 1 root@smarc-rzg2l:~# cat /sys/class/gpio/gpio460/value # after switch off 0
One way to work with GPIO interrupts from user space is by polling the GPIO to detect when its value changes. Depending on the mechanism you use to work with GPIOS in user space, there may be dedicated wait() or poll() method for that. For example, the libgpiod has a method called gpiod_line_event_wait() to wait for any event change in GPIO line. Another option is using character device interface, using line evets structures and functions.
Note that for the GPIO pins not all trigger methods are supported. Below are the only trigger methods support by GPIO pins.
For example, if you need a Both-edge interrupt, you will need to use a IRQ0-IRQ7 pin instead.
libgpiod line events handling has the structures and functions to poll lines for events
Data Structures: struct gpiod_line_event Structure holding event info Enumerations enum { GPIOD_LINE_EVENT_RISING_EDGE = 1, GPIOD_LINE_EVENT_FALLING_EDGE } Event types Functions int gpiod_line_event_wait (struct gpiod_line *line, const struct timespec *timeout) Wait for an event on a single line. int gpiod_line_event_wait_bulk (struct gpiod_line_bulk *bulk, const struct timespec *timeout, struct gpiod_line_bulk *event_bulk) Wait for events on a set of lines. int gpiod_line_event_read (struct gpiod_line *line, struct gpiod_line_event *event) Read the last event from the GPIO line.
user_key { compatible = "gpio-keys"; pinctrl-names = "default"; #address-cells = <1>; #size-cells = <0>; pinctrl-0 = <&user_key_pin>; button@1{ interrupt-parent = <&intc_ex>; interrupts = <7 IRQ_TYPE_EDGE_BOTH>; linux,code = <KEY_3>; label = "SW1"; debounce-interval = <50>; }; };
Mapping to GPIO pin:
&pinctrl{ user_key_pin: user_key { pinmux = <RZG2L_PORT_PINMUX(3, 1, 1)>; /* IRQ7 */ }; };
Enable the IRQ in device tree if it is not enabled by default
&intc_ex { status = "okay"; };
root@smarc-rzg2l:~# cat /proc/interrupts | grep SW1 226: 0 0 110a0000.intc_ex 7 Edge SW1 root@smarc-rzg2l:~# cat /proc/interrupts | grep SW1 226: 2 0 110a0000.intc_ex 7 Edge SW1 root@smarc-rzg2l:~# cat /proc/interrupts | grep SW1 226: 4 0 110a0000.intc_ex 7 Edge SW1
IMAGE_INSTALL_append = " evtest lib32-evtest"
root@smarc-rzg2l:~# evtest /dev/input/event0 Input driver version is 1.0.1 Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100 Input device name: "user_key" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 4 (KEY_3) Properties: Testing ... (interrupt to exit) Event: time 1678155326.1678155326, type 1 (EV_KEY), code 4 (KEY_3), value 1 Event: time 1678155326.1678155326, -------------- SYN_REPORT ------------ Event: time 1678155326.1678155326, type 1 (EV_KEY), code 4 (KEY_3), value 0 Event: time 1678155326.1678155326, -------------- SYN_REPORT ------------ Event: time 1678155326.1678155326, type 1 (EV_KEY), code 4 (KEY_3), value 1 Event: time 1678155326.1678155326, -------------- SYN_REPORT ------------ Event: time 1678155326.1678155326, type 1 (EV_KEY), code 4 (KEY_3), value 0 Event: time 1678155326.1678155326, -------------- SYN_REPORT ------------
This is the instruction to show custom centered kernel boot logo without console text.
jpegtopnm custom_logo.jpg > custom_logo.ppm
ppmquant 224 custom_logo.ppm > custom_logo_224.ppm
pnmtoplainpnm custom_logo_224.ppm > logo_linux_clut224.ppm
find "if (fb_center_logo)" line and replace "fb_center_logo" by "true"
Find for the "fbcon_prepare_logo" function.
After the line "logo_height = fb_prepare_logo(info, ops->rotate);"
insert logo_height += (info->var.yres/2)-(logo_height/2);
To force the logo to show even if the "quiet" command line is enable
Find "CONSOLE_LOGLEVEL_QUIET" variable, and delete/comment out below lines:
if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET)
logo_shown = FBCON_LOGO_DONTSHOW;
Change the boot argument as below
setenv bootargs 'root=/dev/mmcblk1p2 rootwait quite console=ttySC0 vt.global_cursor_default=0'
Reboot the board and your custom logo will appear on early boot.
The Framebuffer console is supported via CONFIG_FRAMEBUFFER_CONSOLE setting in the kernel.
Currently, if CONFIG_EXPERT is not enabled, CONFIG_FRAMEBUFFER_CONSOLE will be enabled and logs will be dumped on your display console.
To disable it, please set "CONFIG_EXPERT=y" in your defconfig (arch/arm64/configs/defconfig). CONFIG_FRAMEBUFFER_CONSOLE will be disabled.