Porting the Panthor Driver for RK3588

The RK3588’s GPU is the Mali G610, and this driver has already been merged into the mainline Mesa. For the community, the well-known open-source organization Collabora has open-sourced the Panthor solution based on Mali. The Mesa side uses the mainline version, and the kernel update is based on the Linux 6.8 Panthor driver. The details of the article are as follows:

https://www.collabora.com/news-and-blog/news-and-events/release-the-panthor.html

1. MESA Update

For Mesa, we need to update to this commit:

https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26358

We switch to the Mesa repository, and we can compile directly for the Mali GPU as follows:

meson . build/ -Dvulkan-drivers= -Dgallium-drivers=panfrost -Dllvm=disabled

The corresponding documentation is as follows:

https://docs.mesa3d.org/drivers/panfrost.html

2. Kernel Update

For the kernel, the default Mesa corresponding Panthor version is on 6.8, and we need to update the following repository:

https://gitlab.freedesktop.org/panfrost/linux/-/tree/panthor-next+rk3588?ref_type=heads

The main code is in:<span>driver/gpu/drm/panthor</span>

We need to port the code here to our version, for example, Linux 6.1 (verified) / Linux 5.10 (unverified).

3. Firmware Update

We know that the Mali GPU supports CSF firmware loading, and this firmware has also been submitted to the community, which can be obtained from the following repository:

https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git

We need a file named mali_csffw.bin to be placed in the system environment or merged into the kernel, loaded via firmware_request.

4. Porting Steps

4.1 Mesa

For Mesa, we need to switch to the 24.1.0 branch for building. If we need binaries, we can find Oibaf’s daily builds from the Ubuntu community as follows:

https://launchpad.net/~oibaf/+archive/ubuntu/graphics-drivers

For specific versions, modify the version number in the download link to download the specified version.

Of course, if we do not need the deb packages of Mesa, we can still build directly using Meson as follows:

meson . build/ -Dvulkan-drivers= -Dgallium-drivers=panfrost -Dllvm=disabled

4.2 Kernel

Enable defconfig as follows:

CONFIG_DRM=y
CONFIG_DRM_GPUVM=y 
CONFIG_DRM_EXEC=y
CONFIG_DRM_SCHED=y
CONFIG_IOMMU_SUPPORT=y 
CONFIG_IOMMU_IO_PGTABLE_LPAE=y 
CONFIG_DRM_GEM_SHMEM_HELPER=y
CONFIG_PM_DEVFREQ=y 
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_DRM_PANTHOR=y
CONFIG_ROCKCHIP_REGULATOR_COUPLER=y
CONFIG_DRM_GPUVM=y

Integrate the Panthor driver as follows:

0041-panthor-v6.txt

The device tree needs to disable the original Mali GPU node and add a node based on Panthor as follows:

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Boris Brezillon &lt;[email protected]&gt;
Date: Mon, 7 Aug 2023 17:30:58 +0200
Subject: arm64: dts: rockchip: rk3588: Add GPU nodes


Signed-off-by: Sebastian Reichel &lt;[email protected]&gt;

---

 arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 119 ++++++++++

 1 file changed, 119 insertions(+)




diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 762a095648b1..f43f10340d5d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi

@@ -962,6 +962,120 @@ usb_host2_xhci: usb@fcd00000 {
        snps,dis-del-phy-power-chg-quirk;
        snps,dis-tx-ipgap-linecheck-quirk;
        snps,dis_rxdet_inp3_quirk;
+   };
+
+   gpu_opp_table: gpu-opp-table {
+       compatible = "operating-points-v2";
+
+       nvmem-cells = &lt;&amp;gpu_leakage&gt;;
+       nvmem-cell-names = "leakage";
+
+       rockchip,pvtm-voltage-sel = &lt;
+           0   815 0
+           816 835 1
+           836 860 2
+           861 885 3
+           886 910 4
+           911 9999    5
+       &gt;;
+       rockchip,pvtm-pvtpll;
+       rockchip,pvtm-offset = &lt;0x1c&gt;;
+       rockchip,pvtm-sample-time = &lt;1100&gt;;
+       rockchip,pvtm-freq = &lt;800000&gt;;
+       rockchip,pvtm-volt = &lt;750000&gt;;
+       rockchip,pvtm-ref-temp = &lt;25&gt;;
+       rockchip,pvtm-temp-prop = &lt;(-135) (-135)&gt;;
+       rockchip,pvtm-thermal-zone = "gpu-thermal";
+
+       clocks = &lt;&amp;cru CLK_GPU&gt;;
+       clock-names = "clk";
+       rockchip,grf = &lt;&amp;gpu_grf&gt;;
+       volt-mem-read-margin = &lt;
+           855000  1
+           765000  2
+           675000  3
+           495000  4
+       &gt;;
+       low-volt-mem-read-margin = &lt;4&gt;;
+       intermediate-threshold-freq = &lt;400000&gt;;   /* KHz */
+       rockchip,temp-hysteresis = &lt;5000&gt;;
+       rockchip,low-temp = &lt;10000&gt;;
+       rockchip,low-temp-min-volt = &lt;750000&gt;;
+       rockchip,high-temp = &lt;85000&gt;;
+       rockchip,high-temp-max-freq = &lt;800000&gt;;
+
+       opp-300000000 {
+           opp-hz = /bits/ 64 &lt;300000000&gt;;
+           opp-microvolt = &lt;675000 675000 850000&gt;;
+       };
+       opp-400000000 {
+           opp-hz = /bits/ 64 &lt;400000000&gt;;
+           opp-microvolt = &lt;675000 675000 850000&gt;;
+       };
+       opp-500000000 {
+           opp-hz = /bits/ 64 &lt;500000000&gt;;
+           opp-microvolt = &lt;675000 675000 850000&gt;;
+       };
+       opp-600000000 {
+           opp-hz = /bits/ 64 &lt;600000000&gt;;
+           opp-microvolt = &lt;675000 675000 850000&gt;;
+       };
+       opp-700000000 {
+           opp-hz = /bits/ 64 &lt;700000000&gt;;
+           opp-microvolt = &lt;700000 700000 850000&gt;;
+           opp-microvolt-L2 = &lt;687500 687500 850000&gt;;
+           opp-microvolt-L3 = &lt;675000 675000 850000&gt;;
+           opp-microvolt-L4 = &lt;675000 675000 850000&gt;;
+           opp-microvolt-L5 = &lt;675000 675000 850000&gt;;
+       };
+       opp-800000000 {
+           opp-hz = /bits/ 64 &lt;800000000&gt;;
+           opp-microvolt = &lt;750000 750000 850000&gt;;
+           opp-microvolt-L1 = &lt;737500 737500 850000&gt;;
+           opp-microvolt-L2 = &lt;725000 725000 850000&gt;;
+           opp-microvolt-L3 = &lt;712500 712500 850000&gt;;
+           opp-microvolt-L4 = &lt;700000 700000 850000&gt;;
+           opp-microvolt-L5 = &lt;700000 700000 850000&gt;;
+       };
+       opp-900000000 {
+           opp-hz = /bits/ 64 &lt;900000000&gt;;
+           opp-microvolt = &lt;800000 800000 850000&gt;;
+           opp-microvolt-L1 = &lt;787500 787500 850000&gt;;
+           opp-microvolt-L2 = &lt;775000 775000 850000&gt;;
+           opp-microvolt-L3 = &lt;762500 762500 850000&gt;;
+           opp-microvolt-L4 = &lt;750000 750000 850000&gt;;
+           opp-microvolt-L5 = &lt;737500 737500 850000&gt;;
+       };
+       opp-1000000000 {
+           opp-hz = /bits/ 64 &lt;1000000000&gt;;
+           opp-microvolt = &lt;850000 850000 850000&gt;;
+           opp-microvolt-L1 = &lt;837500 837500 850000&gt;;
+           opp-microvolt-L2 = &lt;825000 825000 850000&gt;;
+           opp-microvolt-L3 = &lt;812500 812500 850000&gt;;
+           opp-microvolt-L4 = &lt;800000 800000 850000&gt;;
+           opp-microvolt-L5 = &lt;787500 787500 850000&gt;;
+       };
+   };
+
+   gpu: gpu@fb000000 {
+       compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
+       reg = &lt;0x0 0xfb000000 0x0 0x200000&gt;;
+       interrupts = &lt;GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0&gt;,
+                &lt;GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0&gt;,
+                &lt;GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0&gt;;
+       interrupt-names = "job", "mmu", "gpu";
+
+       clock-names = "core", "coregroup", "stacks";
+       clocks = &lt;&amp;cru CLK_GPU&gt;, &lt;&amp;cru CLK_GPU_COREGROUP&gt;,
+            &lt;&amp;cru CLK_GPU_STACKS&gt;;
+       assigned-clocks = &lt;&amp;scmi_clk SCMI_CLK_GPU&gt;;
+       assigned-clock-rates = &lt;200000000&gt;;
+       power-domains = &lt;&amp;power RK3588_PD_GPU&gt;;
+       operating-points-v2 = &lt;&amp;gpu_opp_table&gt;;
+       #cooling-cells = &lt;2&gt;;
+       dynamic-power-coefficient = &lt;2982&gt;;
+
        status = "disabled";
    };

@@ -3124,6 +3238,11 @@ gpio4: gpio@fec50000 {
        };
    };

+   gpu_grf: syscon@fd5a0000 {
+       compatible = "rockchip,rk3588-gpu-grf", "syscon";
+       reg = &lt;0x0 0xfd5a0000 0x0 0x100&gt;;
+   };
+
    av1d: video-codec@fdc70000 {
        compatible = "rockchip,rk3588-av1-vpu";
        reg = &lt;0x0 0xfdc70000 0x0 0x800&gt;;
--

For the firmware loading part, if we have initrd, the firmware can be placed in initrd for loading. If not, we can make it self-contained in the kernel, as follows:

diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c
index ef232c0c2049..de85e30241f6 100644
--- a/drivers/gpu/drm/panthor/panthor_fw.c
+++ b/drivers/gpu/drm/panthor/panthor_fw.c
@@ -705,7 +705,7 @@ static int panthor_fw_load(struct panthor_device *ptdev)
                 (u32)GPU_ARCH_MINOR(ptdev-&gt;gpu_info.gpu_id),
                 CSF_FW_NAME);

-       ret = request_firmware(&amp;fw, fw_path, ptdev-&gt;base.dev);
+       ret = request_firmware(&amp;fw, CSF_FW_NAME, ptdev-&gt;base.dev);
        if (ret) {
                drm_err(&amp;ptdev-&gt;base, "Failed to load firmware image '%s'\n",
                        CSF_FW_NAME);
@@ -1367,4 +1367,4 @@ int panthor_fw_init(struct panthor_device *ptdev)
        return ret;

The defconfig settings are as follows:

CONFIG_FW_LOADER=y
CONFIG_EXTRA_FIRMWARE="mali_csffw.bin"
CONFIG_EXTRA_FIRMWARE_DIR="firmware"

At this point, the firmware should be placed in the kernel directory as follows:

firmware/
└── mali_csffw.bin

5. Boot Log

At this point, the porting of Panthor is completely finished. If the kernel Panthor starts successfully, the following log will appear:

[ 10.187485] panthor fb000000.gpu-panthor: [drm] clock rate = 198000000
[ 10.188422] panthor fb000000.gpu-panthor: EM: OPP:400000 is inefficient
[ 10.188429] panthor fb000000.gpu-panthor: EM: OPP:300000 is inefficient
[ 10.188525] panthor fb000000.gpu-panthor: EM: created perf domain
[ 10.188854] panthor fb000000.gpu-panthor: [drm] mali-g610 id 0xa867 major 0x0 minor 0x0 status 0x5
[ 10.188866] panthor fb000000.gpu-panthor: [drm] Features: L2:0x7120306 Tiler:0x809 Mem:0x301 MMU:0x2830 AS:0xff
[ 10.188875] panthor fb000000.gpu-panthor: [drm] shader_present=0x50005 l2_present=0x1 tiler_present=0x1
[ 10.190340] panthor fb000000.gpu-panthor: [drm] Firmware protected mode entry not be supported, ignoring
[ 10.190563] panthor fb000000.gpu-panthor: [drm] CSF FW v1.1.0, Features 0x0 Instrumentation features 0x71
[ 10.190996] [drm] Initialized panthor 1.0.0 20230801 for fb000000.gpu-panthor on minor 1

At this point, we test glmark2 as follows, which indicates that the system has started normally.

root@kylin:~# glmark2
=======================================================
 glmark2 2021.02
=======================================================
 OpenGL Information
 GL_VENDOR: Mesa
 GL_RENDERER: Mali-G610 (Panfrost)
 GL_VERSION: 3.1 Mesa 24.1.0-devel-panthor (git-1c769cb2b0)
=======================================================
[build] use-vbo=false: FPS: 2859 FrameTime: 0.538 ms

# Building a World-Class Operating System

For more articles, please follow the public account: Kylin Embedded

Leave a Comment