Release time: 2026-03-05 Number of views: 133
This document targets hardware engineers and embedded Linux developers, and introduces the RK3568 GPIO architecture, peripheral interface pinout, and how to configure and use these pins correctly via device tree and Linux user space tools.
The RK3568 SoC integrates a large number of multiplexed pins that can be assigned to different peripheral interfaces or GPIO through the internal pin multiplexing (pinmux) subsystem.
The most commonly used pin categories include:
GPIO pins: General‑purpose input/output used for driving relays, LEDs, reading digital inputs, etc.
Communication interface pins: UART, I2C, SPI, PWM and similar serial interfaces.
Storage interface pins: SDIO, SDMMC, eMMC, SPI Flash, NAND and other storage or wireless modules.
Display interface pins: MIPI‑DSI, RGB/LVDS, HDMI and other display outputs.
High‑speed interface pins: USB 2.0/3.0, PCIe, SATA, Gigabit Ethernet and other high‑bandwidth interconnects.
A single physical pin often supports multiple alternative functions. The actual function takes effect according to the configuration in the device tree and the pinctrl driver during system initialization.
RK3568 GPIOs follow Rockchip’s bank‑based architecture. The processor contains multiple GPIO banks (commonly named GPIO0 through GPIO4). Each bank is divided into four groups labeled A, B, C, and D, and each group includes eight pins numbered 0 to 7.
A typical GPIO name is GPIOx_Yz, where:
x is the bank index (for example, 4),
Y is the group letter A/B/C/D,
z is the pin index within the group (0–7).
In many Linux environments, a global GPIO number is derived from the bank, group, and index. One common scheme treats:
Group A as offset 0–7,
Group B as offset 8–15,
Group C as offset 16–23,
Group D as offset 24–31.
The global GPIO number can then be calculated as:
pin=32×bank+group_offset+index
For example, if GPIO3_A0 uses group offset 0 for group A, its global number is 32×3+0=96. This kind of formula helps convert a pin name such as GPIO4_B3 into a numeric identifier used by some kernel interfaces or legacy tools.
Besides general‑purpose IO, RK3568 integrates many hardware interfaces needed in embedded systems. These interfaces share pins through the pin multiplexing system, so a single pin may support several alternative functions.
Typical interfaces available on RK3568 include:
UART: Used for debug consoles and serial communication with peripherals.
I2C: Used to connect sensors, PMICs, EEPROMs and similar devices.
SPI: Intended for high‑speed peripherals such as ADCs, DACs, industrial controllers or SPI Flash.
PWM: Used for motor control, LED dimming and fan speed control.
SDIO / SDMMC / eMMC: Used for storage devices and wireless modules (e.g., Wi‑Fi/BT combos).
USB 2.0 / USB 3.0: Used for external peripherals like flash drives, cameras and modems.
PCIe: Provides a high‑speed expansion interface for NICs, accelerators, FPGAs, etc.
Gigabit Ethernet: Used for industrial networking and edge computing applications.
Display interfaces: MIPI‑DSI, HDMI, RGB/LVDS, depending on board design and use case.
Understanding which pins are shared between these interfaces is essential. Improper muxing may cause conflicts where enabling one interface disables another.
RK3568 uses a flexible pin multiplexing system controlled by the Linux pinctrl subsystem. During system initialization, the device tree selects which function is assigned to each pin. A pin may be configured as GPIO, UART, SPI, interrupt input, and more, depending on the application requirements.
A typical device tree configuration for UART pins can look like this:
textpinctrl_uart2: uart2-pins { rockchip,pins = , ;};In this example, pins in GPIO bank 3 group C (PC4, PC5) are configured to use function 2, which corresponds to a UART instance, with pull‑up enabled. When designing hardware or debugging interface conflicts, it is important to map these pinctrl settings back to the SoC datasheet and board schematic.
Older Linux kernels exposed GPIO control through the sysfs interface, where developers could export a GPIO and manipulate it via file operations. Modern kernels, however, recommend the libgpiod framework.
With libgpiod, GPIO lines are accessed through gpiochipN character devices. Typical command‑line tools include:
gpioinfo: Query information about all lines on a gpiochip, including name, direction and consumers.
gpioset: Set one or more GPIO lines to a specific output value.
gpioget: Read the current value of one or more GPIO lines.
For example:
bashgpioset gpiochip2 5=1
This command sets line 5 of gpiochip2 to a high level. Using libgpiod is more consistent and future‑proof than relying on the deprecated sysfs interface, and it aligns better with modern kernel GPIO semantics.
When designing carrier boards for RK3568 SoMs (System‑on‑Module) or for discrete RK3568 processors, engineers should pay close attention to pin multiplexing and power domains:
Check for pinmux conflicts: Some pins are shared between critical interfaces such as PCIe, USB 3.0 or SDIO. A wrong choice in hardware can permanently prevent an interface from being used.
Consider IO voltage domains: Different GPIO banks may belong to different voltage domains (for example, 1.8 V or 3.3 V). Ensure external devices match these levels, and add level shifters where needed.
Verify exposed pins: If you use a module, verify which SoC pins are actually routed to the module connector and which are reserved for internal use.
Reference official documentation: Always cross‑check your design with the RK3568 Technical Reference Manual (TRM), datasheet and the module vendor’s reference schematics before finalizing the hardware.
Doing this early reduces the risk of re‑spins and simplifies software bring‑up.
This section summarizes frequent RK3568 pinout‑related problems and gives practical debugging strategies for hardware and embedded Linux engineers.
Boot UART not working
Common causes: wrong pinmux in the device tree, pins shared with other functions (e.g., used as GPIO or an alternate UART), incorrect voltage level between SoC and the USB‑UART adapter.
Debug tips: cross‑check the TRM/datasheet pinmux table against your schematic for the selected UART instance; confirm the pinctrl node for the boot UART is active in the chosen device tree and not overridden by another overlay; measure the TX pin with an oscilloscope or logic analyzer during boot to verify activity and voltage level.
GPIO line cannot be controlled via libgpiod
Common causes: the pin is not configured as GPIO in pinctrl, the line is reserved by a kernel driver (e.g., interrupt line, reset pin), or the GPIO bank power/voltage domain is off or mismatched.
Debug tips: use gpioinfo to check if the line is requested by another consumer and whether it is set as input or output; inspect the corresponding pinctrl group in the device tree to ensure the pin is set to the GPIO function, not a peripheral alternate function; verify the IO voltage domain (e.g., 1.8 V vs 3.3 V) matches the external circuit and that the bank power rail is stable.
Peripheral interface not responding (e.g., I2C/SPI/UART)
Common causes: wrong alternative function selected in pinmux, using the wrong controller instance (e.g., enabling UART2 in the device tree but wiring UART3 pins in hardware), missing pull‑up/down configuration (especially for I2C), or signal direction mismatch.
Debug tips: for I2C, check that SDA/SCL lines have proper pull‑up resistors and verify with a scope that you see start/stop conditions and clock pulses; for SPI/UART, use a logic analyzer to confirm that clock/TX signals are toggling and match the expected pin numbers in the reference manual; compare your device tree pinctrl-0 settings against the reference design from your module/board vendor.
Pin conflict between high‑speed interfaces (PCIe/SDIO/USB)
Common causes: using a pin group for two critical interfaces at the same time due to an unnoticed mux conflict during pin planning.
Debug tips: create a pin‑usage spreadsheet mapping every ball/pad to its function in your design and mark exclusive pins for PCIe, USB 3.0, SDIO and other critical interfaces; compare your pin planning against official reference schematics—if one interface works while another fails, check whether they share any pads in alternative modes; if a conflict is found, resolve it at hardware level (reroute to a different instance/pins) and update the device tree accordingly.
Unexpected pin default state after reset
Common causes: relying on assumed default pull‑up/down or direction while RK3568’s reset configuration or the bootloader changes the pin state.
Debug tips: check the datasheet/TRM for reset‑state tables describing default direction and pull for each bank/pin; inspect the bootloader (e.g., U‑Boot) pinmux and GPIO configuration, as it may reconfigure pins before Linux starts; explicitly set direction and pull in the Linux device tree (both in pinctrl and GPIO consumer nodes) instead of relying on defaults.