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
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
root@smarc-rzg2l:~# cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="user_key"
P: Phys=gpio-keys/input0
S: Sysfs=/devices/platform/user_key/input/input0
U: Uniq=
H: Handlers=kbd event0
B: PROP=0
B: EV=3
B: KEY=10
root@smarc-rzg2l:~# cat /dev/input/event0
�d�
�d�
�d��
�d��
�dr
�dr
�d)B
�d)�d��d��d%Z�d%Z�d/0�d/0�d� �d�
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 ------------
Table of Contents |
---|